Skip to content

Contributing to StateLoom ​

Guide for setting up the development environment, making changes, and submitting contributions.

Prerequisites ​

ToolVersionInstall
Node.js20+nvm install 20
pnpm9+corepack enable && corepack prepare pnpm@latest --activate
Git2.30+System package manager

Setup ​

bash
git clone https://github.com/stateloom/stateloom.git
cd stateloom
corepack enable
pnpm install
pnpm build          # build all packages in dependency order
pnpm test           # run all tests

Verify everything works before making changes.

Development Workflow ​

Working on a Package ​

bash
# Build and watch a specific package
pnpm turbo watch build --filter=@stateloom/core

# Run tests for a specific package
pnpm turbo run test --filter=@stateloom/core

# Run tests in watch mode
pnpm turbo run test:watch --filter=@stateloom/core

# Type check a specific package
pnpm turbo run typecheck --filter=@stateloom/core

Working with Examples ​

bash
# Start React Vite example (with hot reload)
pnpm dev:react-vite

# Start Next.js App Router example
pnpm dev:next-app

Full Validation ​

Before submitting any changes, run:

bash
pnpm lint           # lint all packages
pnpm typecheck      # type check all packages
pnpm build          # build all packages
pnpm test           # run all tests

All four must pass.

Making Changes ​

Branch Naming ​

feat/<description>     # new features
fix/<description>      # bug fixes
refactor/<description> # refactoring
docs/<description>     # documentation only
test/<description>     # test changes only

Commit Convention ​

Use Conventional Commits:

feat(core): add custom equality comparator to signal
fix(react): prevent double-render in StrictMode
docs(store): add middleware composition example
test(atom): add diamond dependency test case
refactor(proxy): extract snapshot logic to separate module
chore: update pnpm to 9.15

Format: <type>(<scope>): <description>

  • type: feat, fix, docs, test, refactor, chore, perf
  • scope: package name without @stateloom/ prefix (e.g., core, react, store)
  • description: imperative mood, lowercase, no period

Code Standards ​

All code must follow the Coding Guidelines. Key rules:

  • Strict TypeScript — no any, no enums, import type for types
  • Named exports only
  • 95%+ test coverage for every package
  • No console.log in library code

Testing Requirements ​

Every code change must include tests:

  1. Write tests alongside code changes
  2. Run pnpm turbo run test --filter=@stateloom/<package> -- --coverage
  3. Ensure 95%+ coverage (statements, branches, functions, lines)
  4. Include type tests using expectTypeOf for public API changes

Documentation Updates ​

If your change affects public API:

  1. Update the relevant package README in docs/api/
  2. Update code examples to reflect new behavior
  3. Update Mermaid diagrams if architecture changed

Changeset Workflow ​

StateLoom uses Changesets for versioning and publishing.

When You Change Published Code ​

bash
pnpm changeset

This prompts you to:

  1. Select which packages changed
  2. Choose version bump type (patch, minor, major)
  3. Write a description of the change

A changeset file is created in .changeset/. Commit it with your changes.

What Gets a Changeset ​

Change TypeNeeds Changeset
Bug fix in published packageYes (patch)
New feature in published packageYes (minor)
Breaking change in published packageYes (major)
Test-only changesNo
Documentation-only changesNo
Example app changesNo
CI/tooling changesNo

Release Process ​

Releases are automated via GitHub Actions:

  1. Changesets accumulate on main
  2. The Changesets GitHub Action opens a "Version Packages" PR
  3. Merging that PR triggers pnpm changeset publish → npm publish

Syncing Example Versions ​

Examples use real npm version ranges (not workspace:^) so that StackBlitz can load them directly from the repo. After bumping package versions, sync the examples:

bash
pnpm sync-example-versions              # reads version from packages/core
pnpm sync-example-versions 1.2.0-beta.0 # explicit version override

This must be run after every version bump. Forgetting this step will break StackBlitz demos.

Adding a New Package ​

bash
pnpm new-package    # interactive scaffold

This generates:

  • packages/<name>/src/index.ts
  • packages/<name>/__tests__/
  • packages/<name>/package.json (with correct exports, peer deps)
  • packages/<name>/tsconfig.json
  • packages/<name>/tsup.config.ts
  • packages/<name>/vitest.config.ts

After scaffolding:

  1. Implement the feature in src/
  2. Write tests in __tests__/
  3. Create documentation in docs/api/<name>/README.md
  4. Run full validation: pnpm lint && pnpm typecheck && pnpm build && pnpm test

CI Pipeline ​

Every PR runs:

StepCommandPurpose
Lintpnpm lintESLint + Prettier
Type Checkpnpm typecheckTypeScript strict mode
Buildpnpm buildtsup (ESM + CJS + dts)
Testpnpm testVitest with coverage
Size Checkpnpm sizeBundle size budget

All steps must pass for the PR to be mergeable.

Architecture Reference ​

Before contributing, familiarize yourself with: