expressjs/express
Development workflow
Active contributors: ulisesgascon, jonchurch, wesleytodd
A typical change to Express follows this loop.
1. Fork and branch
git clone git@github.com:<you>/express.git
cd express
git remote add upstream https://github.com/expressjs/express.git
git checkout -b fix/short-descriptive-name upstream/masterThe default branch is master. CI watches master, develop, 4.x, 5.x, and 5.0 (see .github/workflows/ci.yml).
2. Install dependencies
npm installThere is no separate "build" step. The published artifact is the source.
3. Make the change
Touch only what you need:
- API surface changes →
lib/ - Tests →
test/(mirror the file you changed: a change inlib/response.jstypically has tests across multipletest/res.*.jsfiles) - Examples →
examples/<topic>/
Add an entry to the # Unreleased Changes section at the top of History.md for any user-visible change. The format is a bullet describing the change with an attribution and PR link, e.g.:
- Improve HTML structure in `res.redirect()` responses ... - by [@User](https://github.com/User) in [#1234](https://github.com/expressjs/express/pull/1234)4. Run the local checks
npm run lint
npm testOptionally:
npm run test-cov # HTML coverage at coverage/index.html
npx mocha test/<file>.js # Run a single test file
npx mocha --grep <name> # Run tests matching a name5. Commit
Commit messages in master's history are usually concise and prefixed:
| Prefix | When |
|---|---|
fix: |
Bug fixes (e.g., fix: bump qs minimum to ^6.14.2 ...) |
feat: |
New feature (e.g., feat: Allow passing null or undefined ...) |
docs: |
Documentation-only changes (e.g., docs: update npm install docs URL ...) |
test: |
Test-only additions/changes |
refactor: |
Internal refactoring without behaviour changes |
perf: |
Performance improvements |
build(deps): |
Dependency bumps (mostly automated by Dependabot) |
Sign-off is not required by the project bot, but commit messages should be descriptive enough that the changelog entry can be derived from them.
6. Open a PR
Push your branch to your fork and open a PR against master. The PR description should:
- Link any related issues with
Fixes #1234. - Describe the user-visible change.
- Mention any compatibility or breaking-change implications.
- Note any test coverage you added or removed.
CI runs automatically:
- Lint job —
npm run lint. - Test matrix —
npm run test-ciacross Node 18–25 on Ubuntu and Windows. - Coverage merge — Uploads merged lcov to Coveralls.
- CodeQL scan — Static analysis (
.github/workflows/codeql.yml). - OpenSSF Scorecard — Supply-chain hygiene checks (
.github/workflows/scorecard.yml).
7. Review and merge
Reviews are typically handled by TC members and active triagers. Feedback is the norm — Express's review bar is high because of its install base.
When the PR is ready, a TC member merges it. Some PRs are squashed; others use the merge commit verbatim.
Backports
Active maintenance branches include 4.x. Bug fixes may be cherry-picked to 4.x after landing on master. The TC decides what is in scope for older lines.
Releases
Releases happen on the TC's cadence. The release process is not automated in this repository — History.md's top section is converted into a release header and a corresponding tag is cut.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.