Contributing to Photon
Thanks for wanting to help. Photon is small on purpose, so the bar for adding things is high and the bar for fixing things is low. Bug reports, failing tests, documentation fixes, and measurements are the most valuable contributions.
Before you start
Section titled “Before you start”- Bugs: open an issue with a minimal program that reproduces it. A failing test is even better.
- Features: open an issue first and describe the problem, not the solution. Photon’s core stays small — see ADR-0011 for the test every addition has to pass. Many good ideas belong in your application or in a separate package, and an issue is the cheap way to find out.
- Security issues: do not open an issue. See SECURITY.md.
Development
Section titled “Development”You need Go 1.24 or newer. The race detector also needs a C toolchain with
CGO_ENABLED=1 (on Windows, MinGW-w64 or LLVM-MinGW).
make test # go test ./...make race # the race detector, three runs - the gate that mattersmake check # gofmt, go vet, and the docs coverage testmake fuzz # the routing and SSE framing fuzzers, 30 s eachmake bench # microbenchmarksmake all-modules # also the example backend and the benchmark harness modulesNo make? Every target is one Go command; read the Makefile. On
Windows, .\test.ps1 runs every module.
The repository holds four Go modules: the library at the root, and
examples/openai-backend, bench/baseline, and bench/stream, which have
their own dependencies. go test ./... from the root covers only the first.
What a good pull request looks like
Section titled “What a good pull request looks like”- One change. A fix and a refactor are two pull requests.
- A test that fails without the change. For a bug, the test reproduces it. For behaviour, the test pins it. Several tests here were proven by sabotage — break the code, watch the test fail — and that is the standard.
- Measurements for performance claims. Run the before and after interleaved, as described in bench/RESULTS-2026-10.md, and report medians and ranges. A single run on a laptop is not evidence.
- Documentation updated in the same commit. Every exported symbol must appear in docs/API.md (a test enforces it), and behaviour changes go in CHANGELOG.md under Unreleased.
- No new dependencies in the root module. This is enforced in CI and is not negotiable — see ADR-0013.
Code style
Section titled “Code style”gofmtandgo vetclean.- Comments explain why. The codebase is heavily commented with the reasoning behind each decision, and the reviewer will ask for the reason if it is missing. A comment that restates the code can go.
- Error messages say what happened and what to do: “MaxStreams is -1: use 0 for the derived default” rather than “invalid value”.
- Security-relevant defaults do not change without discussion; changing one is a breaking change.
Design records
Section titled “Design records”Significant decisions are written down in docs/adr/. If your change reverses or amends one, add a dated amendment to that ADR explaining what was learned. Those amendments are the most useful documents in the repository, because a decision that is never revisited is not a decision.
License
Section titled “License”By contributing you agree that your contribution is licensed under the project’s Apache License 2.0, as described in its section 5.