Continuous integration
CI runs checks on every push and pull request, and the repository gives AI coding agents guides to follow.
Litestore checks every change with one script, bun run verify, which runs the type checker, Biome and the unit tests. GitHub Actions runs the same script on every push to main and on every pull request, so a change that passes on your machine also passes in CI. The repository also includes written guides that tell an AI coding agent how the codebase is organised.
verify
verify is defined in package.json as three scripts joined with &&:
"verify": "bun run typecheck && bun run lint && bun run test"| Step | What it runs | What it catches |
|---|---|---|
typecheck | tsc --noEmit with a 5 GB Node heap | Type errors anywhere in the project. |
lint | biome check --write . | Lint errors and formatting. Biome writes the fixes it can make, and the step fails on anything it can't fix. |
test | vitest run | Failing unit tests. The unit tests mock the database, so this step doesn't need Postgres. |
The script stops at the first step that fails. Type checking runs first because it's the slowest step and the one most likely to fail after a large change.
Run bun run verify before you push. If it passes locally, CI will run the same steps on the same code.
GitHub Actions
The workflow is in .github/workflows/verify.yml. It runs on every push to main and on every pull request.
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
with:
bun-version: 1.2.2
- run: bun install --frozen-lockfile
- run: bun run icons
- run: bun run verifyThe job installs Bun 1.2.2, which is the version pinned in the packageManager field. bun install --frozen-lockfile fails if bun.lock doesn't match package.json, so a dependency change has to include the updated lockfile.
bun run icons runs before verify because Git ignores the icon sprite and platform/types/icons.d.ts, and typecheck needs them.
The workflow sets DATABASE_URL to a placeholder value. prisma generate runs during bun install and needs the variable to be present, but nothing in the job connects to a database.
Local-only tests
The integration and end-to-end tests need a running Postgres database, so they aren't part of verify and CI doesn't run them. Run them yourself when you change code they cover.
| Script | What it runs | What it needs |
|---|---|---|
test:integration | The Vitest suites in test/integration/ | A local litestore_test database. |
test:e2e | The Playwright journeys in test/e2e/ | A local litestore_e2e database. Stripe and S3 are replaced by local mocks. |
eval:ai | The AI assistant against the cases in test/evals/cases.ts | An AI provider key. |
The end-to-end tests cover the main journeys through the store, including a shopper buying something, search and the customer account, messaging, reviews, the creator programme and each admin section. The repository treats a feature as finished when its journey test passes against a seeded database.
Agent guides
The repository includes ten guides in .claude/guides/, linked from .claude/CLAUDE.md. They're written for AI coding agents such as Claude Code, so that an agent's changes follow the conventions already in the codebase. They're also useful for people who are new to the code. Each guide is also available as a skill that Claude Code runs by name, for example /before-building.
| Guide | What it covers |
|---|---|
design-review.md | A checklist to go through before you build anything non-trivial. |
before-building.md | Before you write a new page, model or module, you name the existing one you're copying, or you stop and ask. |
code-style.md | The conventions the codebase follows, with the reason for each one. |
style-guide.md | Detailed formatting and naming rules, such as when to use function declarations. |
ui-components.md | Which shared component to use, and when a new one is justified. |
data-api.md | How queries, server actions and cache tags are structured, and where each one goes. |
new-entity.md | Every step for adding a model, from the schema through the admin table to activity logging. |
schema-conventions.md | How to model a field so that Postgres or TypeScript can reject invalid values. |
platform-primitives.md | The standard patterns for lifecycle, queues, publish gates, registries and alerting. |
project-specific.md | The rules that only apply to Litestore, including the money and inventory constraints. |
GUARANTEES.md in the repository root lists the guarantees about money, refunds, stock and data that the code relies on, and the guides tell an agent to read it before changing any of those areas.