Skip to content
Get started
Get started
Contributing to bunqueue: Development & PR Guide
View Markdown
project · contributing

Contribute to bunqueue, ship a PR.

Dev environment setup, coding standards, testing guidelines and the pull request workflow. Everything you need to land a change, whatever your experience level.

Be respectful and inclusive. We welcome contributors of all backgrounds and experience levels.

  • Bun v1.4.0+
  • Git
  • A GitHub account
# Fork the repo on GitHub, then:
git clone https://github.com/YOUR_USERNAME/bunqueue.git
cd bunqueue
bun install

There are three suites. All three must pass before any change lands:

# Unit tests (four isolated file workers)
bun test --parallel=4
# TCP integration tests (~50 suites, spawns a real server)
bun scripts/tcp/run-all-tests.ts
# Embedded integration tests (~35 suites)
bun scripts/embedded/run-all-tests.ts

Other useful invocations:

# Run a specific test file
bun test test/queueManager.test.ts
# Run the generated real-broker state model
bun run test:model
# Reproduce or deepen a model campaign
BUNQUEUE_MODEL_RUNS=500 BUNQUEUE_MODEL_COMMANDS=150 \
BUNQUEUE_MODEL_SEED=-1959189325 bun run test:model
# Run the full unit suite with coverage
bun test --parallel=4 --coverage

Note: bun test preloads test/preload.ts, which sets BUNQUEUE_EMBEDDED=1. The full unit command uses four isolated worker processes; tests inside an individual file remain serial. Tests that need real TCP behavior must opt out with an explicit embedded: false and spawn a server.

Changes to queue lifecycle, persistence/recovery, scheduling, dependencies, deduplication, leases, limits, TTL, counters, or indexes must run bun run test:model during iteration. The model uses real TCP, SQLite, and SIGKILL; failures include a seed and minimized command history. Preserve every confirmed engine divergence as a deterministic test/repro-model-*.test.ts before fixing it. The model run is required in addition to the final isolated bun run test:sandbox gate.

We use Bun’s built-in tools only: bun check for type checking and bun fmt for formatting, configured in the [fmt] section of bunfig.toml. They are the only type-check and format tools for JavaScript and TypeScript, in this repository and in every SDK: ESLint, Prettier, Biome, oxlint, oxfmt and tsc --noEmit are not used, and there is no JavaScript linter. SDKs in other languages keep their own toolchain (gofmt, go vet, cargo fmt, cargo clippy, mix format, php -l).

# Type check. It first rebuilds what the test tree imports (the SDK build,
# the package build, the docs dependencies), so it never reads a stale build.
bun run typecheck
# Format code
bun run format
# Format verification (what CI / the pre-commit hook run, with typecheck)
bun run format:check
  • feat/description - New features
  • fix/description - Bug fixes
  • docs/description - Documentation
  • refactor/description - Code refactoring
  • test/description - Test additions

Follow Conventional Commits:

feat: add stall detection for workers
fix: resolve memory leak in event listeners
docs: update API reference
refactor: simplify batch operations
test: add DLQ filtering tests
  1. Create a feature branch
  2. Make your changes
  3. Add/update tests
  4. Update documentation: the internal reference under docs/ (docs/README.md, docs/architecture.md, docs/data-model.md, docs/features/*.md) in the same change as the code, and the changelog (docs/src/content/docs/changelog.md) in every commit
  5. Run bun run test:model for core queue changes, then the authoritative bun run test:sandbox gate (plus bun run test:sandbox:sdk after any change under sdk/), bun run typecheck and bun run format:check
  6. Push and create a PR
## Description
Brief description of changes
## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation
## Testing
How was this tested?
## Checklist
- [ ] Tests pass
- [ ] `bun run typecheck` and `bun run format:check` pass
- [ ] Documentation updated
src/
├── cli/ # CLI commands
├── client/ # Embedded client SDK
├── domain/ # Core business logic
├── application/ # Use cases
├── infrastructure/ # External services
└── shared/ # Utilities
  • src/domain/queue/shard.ts - Queue sharding logic
  • src/application/queueManager.ts - Central coordinator
  • src/client/queue/queue.ts - Client Queue class
  • src/client/worker/worker.ts - Client Worker class
  • Max 300 lines per file
  • Split if larger
  1. jobIndex
  2. completedJobs
  3. shards[N]
  4. processingShards[N]
  • Use bounded collections
  • Clean up event listeners
  • Release resources in shutdown
describe('Feature', () => {
beforeEach(() => {
// Setup
});
afterEach(() => {
// Cleanup
});
it('should do something', () => {
// Test
});
});
  • Happy path
  • Edge cases
  • Error handling
  • Concurrent operations
  • Generated state transitions and crash/recovery invariants for core queue changes
/** Brief description */
function simpleFunction() {}
/**
* Longer description for complex functions
* @param input - Description
* @returns Description
*/
function complexFunction(input: string): Result {}

Update README.md for:

  • New features
  • Changed APIs
  • New environment variables

Releases are handled by the maintainer. Every release:

  1. Bumps the version in package.json
  2. Updates the changelog (docs/src/content/docs/changelog.md)
  3. Publishes to npm from GitHub Actions through npm trusted publishing, with a provenance attestation; packages are never published from a local machine

Contributors are listed in:

  • GitHub contributors page
  • The “Thanks to N contributors!” section of each release blog post

Thank you for contributing!