Contributing
Contributing
Set up the repo, run the tests you can run, and send a pull request that can be reviewed.
Pooled has three parts: a WebGPU engine, a peer-to-peer room runtime over WebRTC, and Code mode, an in-browser coding agent. Help is welcome on all of them, on the site and docs, and with benchmark reports from hardware we don’t have.
Shortest path: clone, npm test (no GPU needed), npm run serve, then open a PR with one change and the tests you ran.
Before you start
Section titled “Before you start”- Search the issues; for anything bigger than a small fix, open one first to agree on the approach.
- One change per PR. Refactors and behavior changes go in separate PRs.
- Usage questions go in Discussions. Security issues are reported privately (Security model).
Changes that need a design note first
Section titled “Changes that need a design note first”Open an issue with the Research / design proposal template before you write code for any of these:
- a change to the peer-to-peer protocol (message types, frame format, room lifecycle);
- a new model architecture or quantization format in the engine;
- anything that changes model output;
- a new dependency or a build step;
- anything that changes what peers can learn about each other.
What won’t be accepted
Section titled “What won’t be accepted”A proposal that conflicts with these commitments is declined, however good the code is:
- Easy to use. Opening a room link in a browser must always work with nothing installed. Native and headless peers are welcome, but they must never become a requirement.
- No accounts, no tokens, no ads.
- Honest claims. Speed numbers come with the commit and hardware that produced them. Privacy claims must match the security model.
- Bit-exact output by default. An optimization must reproduce the reference output. An approximation needs an explicit, documented switch that is off by default.
Set up
Section titled “Set up”-
Clone the repo and install Deno 2. The engine’s tests run in Deno, which ships WebGPU.
git clone https://github.com/Nehanth/pooled && cd pooledcurl -fsSL https://deno.land/install.sh | sh -
Run the unit tests. They need no GPU.
npm test -
Serve the site and open the room at
http://localhost:8080/room.npm run serve -
For the browser tests, run
npm installto get Playwright and thepeersignaling server.
Model files aren’t in the repo; GPU tests read them from models/. See Testing.
Pull requests
Section titled “Pull requests”Before you open one:
- Engine changes keep the golden tests passing bit for bit, and speculative decoding equal to plain (
tests/test_mtp.js). - Speed changes add a row to
docs/bench-log.md(neutral results too). “Faster” without a number can’t be reviewed. See Benchmarking. - Protocol changes make older peers fail loudly: bump the message version.
- Add or update a test:
tests/(GPU),tests/unit/(no GPU),tests/e2e/(browser). - Code mode changes keep
npm run e2e:codeandnode tests/e2e/preview_browser.mjspassing. - Keep the diff readable: no reformatting or renaming you don’t need.
- User-facing changes update the docs.
Commit messages: write an imperative subject under 72 characters, and a body that says why. For performance work, include the measured effect.
After you open it: CI runs the syntax checks and unit tests. GPU tests run on the maintainer’s hardware before merge, so fill in the template’s “Tested on” with the tests and GPU you used. Merging to main deploys to production.
AI usage policy
Section titled “AI usage policy”You can use AI, but you are responsible for the code: read it, run it, and be ready to explain it. PRs that show no sign of having been run (failing tests, invented APIs, unmeasured speed claims) are closed. Don’t paste raw model output into issues or reviews. Point coding agents at docs/agents.md.
Coding guidelines
Section titled “Coding guidelines”- Plain modern JavaScript, ES modules, no build step, no framework.
- Kernels are JavaScript templates in
engine/wgsl/*.jsthat generate deterministic, readable WGSL. - Rules we learned the hard way:
- Never index a local array with a runtime value in WGSL. It spills to memory and runs about 3 times slower.
- Keep
workgroupBarrier()outside conditionals. - Accumulate in f32. f16 accumulation corrupted the output.
- Don’t use subgroups or pointer parameters without a probe and a fallback. Safari 26 has neither.
- Dispatch tall matrix-vector products in 2-D. A dispatch with more than 65,535 workgroups in one dimension is silently dropped.
- Portability. Everything runs in Chrome, Safari 26 and Deno. Detect features at runtime.
- Measure, don’t reason.
tests/prof_ts.jsfor per-kernel time,tests/bench/chrome_bench.mjsfor Chrome numbers. - One GPU job at a time, or every number is meaningless.
Naming
Section titled “Naming”| What | Convention | Example |
|---|---|---|
| Engine files | short, lowercase | gguf.js, quant.js |
| Room and harness modules | kebab-case | code-ui.js, engine-model.js |
| GPU tests | tests/test_<what>.js |
tests/test_mtp.js |
| Unit tests | tests/unit/<what>_test.js |
tests/unit/errors_test.js |
| Benchmarks | bench_<what>.js |
benchmarks/bench_gemm.js |
| Kernels | <op>[_<quant>][_<variant>] |
matvec_q4_coop_b, dn_delta_mc |
| Protocol messages | ai-<verb> with a t field |
ai-load, ai-linked |
Kernel suffixes: _coop is cooperative rows, _b batched columns, _acc accumulates into the output, _mc is multi-column glue, and _gu fuses gate and up.
Where to read next
Section titled “Where to read next”Architecture, Engine and kernels, Wire protocol, Testing, Adding a model, Benchmarking, Releases and the Roadmap.
Contributors are listed in AUTHORS. Everyone in the project follows the Code of Conduct.