Contributing

Prerequisites, quality gates, changeset workflow, and house style for contributors.

Prerequisites

  • Node.js (version pinned in .nvmrc)
  • pnpm
  • A Convex deployment in CONVEX_URL (pnpm convex:dev provisions an anonymous local backend)

After cloning:

pnpm install
pnpm build:packages   # apps depend on each package's dist/, not source

pnpm build:packages must succeed before you run lint, typecheck, or tests in a fresh checkout — it compiles every workspace package into dist/ so the apps can import them.

Quality gates

Before opening a PR, the following must pass locally:

pnpm lint        # Biome lint (includes unsafe fixes like Tailwind class sorting)
pnpm typecheck   # turbo run typecheck across all packages and apps
pnpm test        # Vitest — unit suites run convex-test in-memory, no backend needed

CI runs the same set in parallel on every PR. A PR with failing checks will not be merged.

Note

pnpm test runs Vitest with --coverage. The limit-boundary suites in packages/test-convex/src/limits boot a REAL local Convex backend — CI runs them whenever packages/convex/** or packages/test-convex/** changes.

Changesets

Touching any package not in .changeset/config.json's ignore list requires a changeset:

pnpm changeset   # interactive — choose packages and bump level

Pick the semver level per the nature of the change:

LevelWhen
patchBug fix or internal-only change with no API surface change
minorAdditive change — new export, new optional option
majorBreaking change — removed export, changed signature

One changeset per logical change. The changeset summary follows the same WHY-only rule as commit bodies — explain motivation and context, not what the diff already shows.

Commit conventions

All commits follow Conventional Commits with scope:

<type>(<scope>): <subject>.

Types: feat, fix, chore, refactor, docs, test, perf, ci, build. Subject is imperative, lowercase, with a trailing period. Example:

fix(cms): resolve locale fallback when shop default is unset.

The commit body explains why — motivation, hidden constraints, trade-offs, breaking changes. Skip the body entirely if the subject and diff are self-explanatory.

Watch out

Never merge — always rebase. No merge commits on any branch. If a PR cannot fast-forward, rebase the branch onto the target before merging. When iterating on the most recent commit (review feedback, typo), prefer git commit --amend over stacking fixup commits.

Pull request process

  1. Branch from master, name it feat/<kebab-slug> or fix/<kebab-slug>.
  2. Run quality gates locally before pushing.
  3. Open a PR — the CI runs lint, typecheck, and tests automatically.
  4. Add a changeset if you touched any non-ignored package.
  5. Request a review once CI is green.
Continue exploring

On this page