Litestore · Developer docs
Testing

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.

Postgres 15+Your data
RedisCache and rate limits
S3 storageImages
LitestoreOne Next.js app
StorefrontAdmin
ResendEmail and sign-in links
InngestBackground jobs
StripeOptional
CI runs the same verify script you run locally, and none of it sends the code to an outside service.

verify

verify is defined in package.json as three scripts joined with &&:

package.json
"verify": "bun run typecheck && bun run lint && bun run test"
StepWhat it runsWhat it catches
typechecktsc --noEmit with a 5 GB Node heapType errors anywhere in the project.
lintbiome check --write .Lint errors and formatting. Biome writes the fixes it can make, and the step fails on anything it can't fix.
testvitest runFailing 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.

.github/workflows/verify.yml
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 verify

The 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.

ScriptWhat it runsWhat it needs
test:integrationThe Vitest suites in test/integration/A local litestore_test database.
test:e2eThe Playwright journeys in test/e2e/A local litestore_e2e database. Stripe and S3 are replaced by local mocks.
eval:aiThe AI assistant against the cases in test/evals/cases.tsAn 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.

GuideWhat it covers
design-review.mdA checklist to go through before you build anything non-trivial.
before-building.mdBefore you write a new page, model or module, you name the existing one you're copying, or you stop and ask.
code-style.mdThe conventions the codebase follows, with the reason for each one.
style-guide.mdDetailed formatting and naming rules, such as when to use function declarations.
ui-components.mdWhich shared component to use, and when a new one is justified.
data-api.mdHow queries, server actions and cache tags are structured, and where each one goes.
new-entity.mdEvery step for adding a model, from the schema through the admin table to activity logging.
schema-conventions.mdHow to model a field so that Postgres or TypeScript can reject invalid values.
platform-primitives.mdThe standard patterns for lifecycle, queues, publish gates, registries and alerting.
project-specific.mdThe 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.

On this page