Contributing

May 8, 2026 · View on GitHub

Contentful Logo

Content Delivery API

Contributing

Readme · Migration · Advanced · Typescript · Contributing

Join Contentful Community Slack

PRs Welcome   Semantic Release   JS Standard Style

Contributing

Prerequisites

ToolVersionNotes
Node.js18+CI runs on Node 24; local dev works on 18+
npmlatestnpm install -g npm@latest

Getting Started

# 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

# 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

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 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/<name>, fix/<name>, chore/<name>

Release Process

Releases are fully automated via 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

JobTriggerWhat it does
buildPush, PRnpm cinpm run build → cache dist/
lintPush, PRESLint
prettierPush, PRPrettier format check
testPush, PRVitest (unit + integration) + demo projects
test-bundle-sizePush, PRsize-limit check
test-typesPush, PRtsd type tests + es-check
releasePush to master/nextsemantic-release → npm publish + docs
codeqlPush/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

PathWhy 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.mdAuto-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.tsDeclares __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.