Content Delivery API
Contributing
Readme ·
Migration ·
Advanced ·
Typescript ·
Contributing
# Contributing
## Prerequisites
| Tool | Version | Notes |
|---|---|---|
| Node.js | 18+ | CI runs on Node 24; local dev works on 18+ |
| npm | latest | `npm install -g npm@latest` |
## Getting Started
```bash
# Clone and install
git clone git@github.com:contentful/contentful.js.git
cd contentful.js
npm ci
# Build (required before running tests)
npm run build
# Run all tests
npm test
```
## Development Workflow
```bash
# Build ESM output only (faster iteration)
npm run build:esm
# Run unit tests in watch mode
npm run test:unit:watch
# Run integration tests in watch mode
npm run test:integration:watch
# Lint
npm run lint
# Format
npm run prettier
```
### Full build pipeline
```bash
npm run build # clean → tsc → rollup (CJS + browser bundles)
npm run check # es-check on all output formats (ES2017/ES2018 compliance)
```
## Testing
- **Framework:** Vitest
- **Location:** `test/unit/`, `test/integration/`, `test/types/`
- **Run all:** `npm test` (unit + integration + lint + type tests)
- **Run unit only:** `npm run test:unit`
- **Run integration only:** `npm run test:integration`
- **Watch mode:** `npm run test:unit:watch`
- **Type tests:** `npm run test:types` (uses `tsd`)
- **Bundle size:** `npm run test:size` (uses `size-limit`)
- **Output integration:** `npm run test:demo-projects` (Node + browser demo projects)
### Test structure
```
test/
├── unit/ Unit tests (mocked HTTP)
├── integration/ Integration tests (mocked CDA responses)
├── types/ Type assertion tests (tsd)
└── output-integration/
├── node/ Verifies the built package works in a Node project
└── browser/ Verifies the built package works in a browser project
```
## Commit Convention
This repo uses [Conventional Commits](https://www.conventionalcommits.org/) enforced by commitizen:
```
type(scope): description
```
Valid types: `feat`, `fix`, `chore`, `docs`, `refactor`, `test`, `perf`, `ci`, `build`, `revert`
Examples:
```
feat: add cursor-based pagination for entries
fix(deps): bump axios to address CVE-2026-40175
build(deps): bump contentful-sdk-core and qs deps
docs: update migration guide for v11
```
A pre-commit hook runs lint-staged (prettier + eslint) via husky.
## Branch Strategy
- `master` — production; semantic-release on every push
- `next` — pre-release channel (when active)
- Feature branches — `feat/`, `fix/`, `chore/`
## Release Process
Releases are fully automated via [semantic-release](https://github.com/semantic-release/semantic-release):
1. Push/merge to `master`
2. CI runs build + all checks
3. If passing, semantic-release determines version from commit history:
- `fix` → patch
- `feat` → minor
- `BREAKING CHANGE` / `feat!` → major
- `build(deps)` → patch
4. Publishes to npm, creates GitHub release, updates CHANGELOG.md
5. Publishes TypeDoc API documentation
**You do not manually bump versions, create tags, or publish.** The commit type determines everything.
Pre-releases are published from the `next` branch when active.
## Pull Requests
- All tests must pass (CI runs on every push and PR)
- Husky pre-commit hook runs lint-staged (prettier + eslint)
- Squash merge to master is standard
- Bundle size is checked in CI via `size-limit`
- Bito automated review runs on every PR using `.bito/guidelines/` as its ruleset
## CI/CD
| Job | Trigger | What it does |
|---|---|---|
| `build` | Push, PR | `npm ci` → `npm run build` → cache dist/ |
| `lint` | Push, PR | ESLint |
| `prettier` | Push, PR | Prettier format check |
| `test` | Push, PR | Vitest (unit + integration) + demo projects |
| `test-bundle-size` | Push, PR | size-limit check |
| `test-types` | Push, PR | tsd type tests + es-check |
| `release` | Push to master/next | semantic-release → npm publish + docs |
| `codeql` | Push/PR (`.github/workflows/**` changes only) | GitHub Actions workflow security scanning |
All workflows live in `.github/workflows/`. The main pipeline is orchestrated by `main.yaml` which calls `build.yaml`, `check.yaml`, and `release.yaml` as reusable workflows.
## File-level Guidance
| Path | Why restricted / notes |
|---|---|
| `dist/` | Generated by `npm run build` — never hand-edit. Committed only via CI release workflow. |
| `dist/esm-raw/` | Intermediate Rollup input — deleted at the end of `npm run build`. Not a shipped output; never reference in `package.json` exports. |
| `CHANGELOG.md` | Auto-generated by semantic-release on every release. Never hand-edit. |
| `package.json` → `"version"` | Managed by semantic-release (`"0.0.0-determined-by-semantic-release"` is intentional). Don't bump manually. |
| `lib/global.d.ts` | Declares `__VERSION__` — replaced at Rollup build time via `@rollup/plugin-replace`. Do not import or rely on its value outside built output. |
| `.husky/` | Husky hook scripts. Runs lint-staged (prettier + eslint) on pre-commit. Don't bypass with `--no-verify` without a very good reason. |
| `test/output-integration/` | Self-contained Node and browser projects that install and smoke-test the built package. Run with `npm run test:demo-projects`. |