Community

Contributing

How to build, test, and submit changes to NextRush — summarized from the repository's own CONTRIBUTING.md, with its stale sections flagged rather than repeated as fact.

The canonical contributor guide is CONTRIBUTING.md at the repository root. This page summarizes it and cross-links to the architecture pages that hold the current, verified version of anything CONTRIBUTING.md states inaccurately — that file is outside this rebuild's apps/website/** file scope, so it hasn't been edited here, but repeating its stale claims as if they were current would defeat the point of this rebuild.

Prerequisites

RequirementVersion
Node.js≥ 22.0.0
pnpmLatest, managed via corepack (ships with Node.js ≥ 22)
GitAny recent version

Getting started

Fork and clone

# Fork on GitHub, then:
git clone https://github.com/YOUR_USERNAME/nextrush.git
cd nextrush

Install dependencies

corepack enable
pnpm install

Install doesn't compile

pnpm install does not run a full build — this matches the root README's own quick-start note. Run pnpm build when you need compiled output from any package.

Build and test

pnpm build
pnpm test

Create a branch

git checkout -b feat/your-feature

Branch prefix matches the commit type: feat/, fix/, docs/, refactor/, test/, perf/, chore/.

Development commands

pnpm build                             # Build all packages
pnpm test                              # Run all tests
pnpm typecheck                         # Type check all packages
pnpm lint                              # Lint all packages
pnpm lint:fix                          # Lint and auto-fix
pnpm format                            # Format
pnpm format:check                      # Check formatting (CI)
pnpm clean                             # Clean build artifacts
pnpm --filter @nextrush/<pkg> test     # Test a specific package
pnpm --filter @nextrush/<pkg> build    # Build a specific package

Coding standards, as stated in CONTRIBUTING.md

  • TypeScript strict mode — zero any usage; ES2022 target; verbatimModuleSyntax enabled (use import type for type-only imports).
  • Naming: camelCase for functions/variables, PascalCase for types/interfaces/classes, SCREAMING_SNAKE_CASE for constants, kebab-case.ts filenames, barrel exports via index.ts.
  • Zero dependencies: no external runtime dependencies beyond the three named exceptions — see Design Principles for the exact list (reflect-metadata, tsyringe, @clack/prompts), which is more precise than CONTRIBUTING.md's own "except reflect-metadata" phrasing (it omits tsyringe and @clack/prompts, both genuinely used per the generated dependency graph).
  • Comments explain why, not what — a comment restating the line below it is noise, not documentation.

Testing

  • Vitest, co-located as src/__tests__/*.test.ts.
  • Coverage target: 90%+ per package (lines, functions, statements; 85%+ branches).
  • Test happy paths, edge cases, and error scenarios — every public export needs at least one test.
  • pnpm --filter @nextrush/core test -- --coverage runs one package's suite with coverage; pnpm test:coverage runs it for the whole workspace.

Making a change

CONTRIBUTING.md's workflow: fork, branch from main (feat/my-feature), make the change following the standards above, add tests, run pnpm build && pnpm typecheck && pnpm test, commit with a type(scope): description message, then open a PR against main.

PR title format

type(scope): description

Examples:
feat(router): add wildcard route support
fix(core): handle async middleware errors
docs(guides): add authentication guide
chore(deps): update typescript to 5.x

Types: feat, fix, docs, chore, refactor, test, perf.

Before submitting

  • Tests pass: pnpm test
  • Coverage meets thresholds: pnpm test:coverage
  • Types check: pnpm typecheck
  • Lint passes: pnpm lint
  • Formatting correct: pnpm format:check
  • Documentation updated (if the change touches public API or behavior)
  • Changeset added (if the change affects a published package)

Review: automated checks must pass, at least one approval is required, and merges are squashed.

Adding a new package

Create the package structure

mkdir -p packages/middleware/my-middleware/src
cd packages/middleware/my-middleware

Add package.json, tsconfig.json, and tsup.config.ts

Copy the shape of an existing package in the same category (e.g. packages/middleware/cors for a new middleware package) rather than writing these from scratch — every package's tsconfig extends the same shared base, and tsup.config.ts follows the same ESM-only, dts: true pattern.

Implement against @nextrush/types, then test

// src/index.ts
import type { Middleware } from '@nextrush/types';

export interface MyMiddlewareOptions {
  // ...
}

export function myMiddleware(options?: MyMiddlewareOptions): Middleware {
  return async (ctx, next) => {
    await next();
  };
}

New packages ship both a README.md and an ARCHITECTURE.md from the templates in docs/templates/ — see Documentation Contributions below.

Documentation contributions

  • Human-first: explain the problem before the API.
  • Show runnable examples: every code block should be something a reader could paste and run.
  • Be accurate: verify signatures and defaults against the real source, not a prior version of the docs — stale documentation is treated as a defect, not a lower-priority fix.
  • Every doc page states its purpose, shows the problem it solves, gives runnable examples, and names common issues — see the Documentation Instructions for the full page-type standards.

CONTRIBUTING.md — previously stale, now corrected

Two claims in the root CONTRIBUTING.md previously didn't match the codebase as it existed at the time. Both have since been corrected directly in that file, and are named here for the record rather than silently dropped:

Package hierarchy diagram and router terminology — fixed

CONTRIBUTING.md used to state the hierarchy as types → errors → core → router → di → decorators → controllers → adapters → middleware and describe the router as "Radix tree routing." Both were pre-consolidation. The file now states the current hierarchy (types → errors → core → router → runtime → di → class → adapters → middleware → extensions) — matching Package Hierarchy (built from every package.json's actual dependencies field) — and correctly describes the router as a segment trie, not a radix tree (see Router Internals). @nextrush/decorators and @nextrush/controllers were deprecated shims over @nextrush/class, removed from the workspace; the hierarchy no longer lists them as standalone steps.

CONTRIBUTING.md's monorepo structure listing now includes @nextrush/class and @nextrush/extensions/ (events, websocket) rather than a decorators/ package and a plugins/ parent directory that no longer exist in the actual packages/ tree.

Package size limits

CONTRIBUTING.md defers to ".github/copilot-instructions.md" for size limits. The verified, current limits (per .kiro/steering/architecture.instructions.md, cross-checked against real package LOC targets) are listed in Package Hierarchy → Package Size Targets.

Getting help

  • Questions: open a Discussion
  • Bugs: open an Issue
  • Code review: request review on your PR
First-time contributors: look for issues labeled good first issue.

Next steps

Was this helpful?

On this page