Litestore · Developer docs
Getting started

Setup

Clone Litestore, load the demo catalog and sign in to the admin on your own computer.

Running Litestore on your computer for the first time follows the quick start in the repository's README.md. Run the steps in order, because that makes it easier to tell a setup problem from a configuration problem. For example, if the schema applies but sign-in fails, the install is fine and one of your keys is probably wrong.

Postgres 15+Your data
RedisCache and rate limits
S3 storageImages
LitestoreOne Next.js app
StorefrontAdmin
ResendEmail and sign-in links
InngestBackground jobs
StripeOptional
Litestore connects to Postgres, Redis and S3 storage, to Inngest for background jobs, and to Resend, Stripe and an AI provider if you add them.

Prerequisites

The repository's README.md asks for Bun and Docker; Docker runs the services in compose.yml. The table lists what the app connects to and says what each one does.

RequirementWhat it does
BunBun installs packages and runs the scripts. The packageManager field pins bun@1.2.2, and .github/workflows/verify.yml installs that same version.
PostgreSQL 15 or newerInstall it locally or run it with the included compose.yml.
Redis or Upstash RedisEvery environment requires REDIS_REST_URL and REDIS_REST_TOKEN. Litestore uses Redis for rate limiting, the checkout payment lock and coupon reservations. Locally, compose.yml runs Redis behind an Upstash-compatible REST proxy.
An S3-compatible bucketUse AWS S3 or Cloudflare R2, or run MinIO locally.
A Resend account (production only)Litestore signs people in with a magic link sent by email. Outside production Litestore never sends email, so you can leave RESEND_API_KEY empty: every email, including the sign-in link, is printed in the terminal running bun run dev. Production refuses to start without the key and sender address.
Docker Compose runs Postgres, Redis and MinIO, so locally you only need Bun and Docker.

Stripe, analytics, Shopify, AI providers and newsletter providers are optional. Shoppers can browse the store and fill a cart without any of them.

Installation steps

Clone

Clone the repository and run every later command from its root.

git clone https://github.com/litestore/litestore
cd litestore
bun install

bun install runs the postinstall hook, which calls db:generate (prisma generate). That writes the typed Prisma client the rest of the app imports.

The repository doesn't install Git hooks. GitHub Actions runs bun run verify on every push and pull request instead.

bun install does not build the icons. Git ignores the icon sprite (public/icons/sprite.svg) and platform/types/icons.d.ts because they are generated, so you run this once after cloning:

bun run icons

Both typecheck and the sprite contract test read those files, and on a fresh clone they fail until you have run this command.

Database

If you already run Postgres locally, create a database named litestore and skip to the next step.

Otherwise, start the services in compose.yml in the background and then check their state.

docker compose up -d
docker compose ps

Compose starts PostgreSQL 17 on port 5432, Redis behind serverless-redis-http on port 8079, and MinIO on ports 9000 and 9001. A setup container creates the media bucket and makes it publicly readable.

Postgres reads DB_USER, DB_PASSWORD and DB_NAME from your env file. If you leave them out, they default to postgres, postgres and litestore.

Environment variables

Copy the example file.

cp .env.example .env.local

.env.example already contains the connection values for the Compose services. The optional keys are empty strings, and env.ts sets emptyStringAsUndefined, so an empty value is treated as unset. Outside production the Resend key and sender address are optional, so the copied file works as it is.

This is the smallest set of values that passes validation:

.env.local
NEXT_PUBLIC_SITE_URL="http://localhost:3000"
NEXT_PUBLIC_SITE_EMAIL="hello@example.com"
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/litestore"

BETTER_AUTH_URL="http://localhost:3000"
BETTER_AUTH_SECRET="replace-with-a-long-random-secret"

# The Upstash-compatible proxy from compose.yml.
REDIS_REST_URL="http://localhost:8079"
REDIS_REST_TOKEN="local-dev-token"

S3_ENDPOINT="http://localhost:9000"
S3_REGION="us-east-1"
S3_BUCKET="litestore"
S3_ACCESS_KEY="litestore"
S3_SECRET_ACCESS_KEY="litestore-secret"
S3_PUBLIC_URL="http://localhost:9000/litestore"

Migrations

This command creates the tables and applies every committed migration.

bun run db:deploy

db:deploy runs prisma migrate deploy, which applies the migrations in prisma/migrations/ that haven't run yet. The first one, 20260726143000_baseline_with_db_guarantees, creates the schema. It also adds the CHECK constraints, the ledger triggers, the drift views and the case-insensitive unique indexes, which Prisma's schema language can't express. Never use prisma db push, which skips all of it.

Seed data

This command loads a working store with products and their variants, inventory, media, pages, reviews, feeds and shipping rates.

bun run db:seed

This runs bun prisma/seed.ts, which is also the seed command that prisma.config.ts registers for prisma migrate reset.

When the seed finishes, it prints a summary. It creates two rows for each of 41 base models and 20 more products with over 80 variants between them. It does not create orders, which you create through checkout or in the admin.

Almost every write in the seed is an upsert, so running it twice updates the existing rows instead of adding duplicates. The seed refuses to run when NODE_ENV is production unless you set SEED_ALLOW_PRODUCTION=1.

Dev server

This runs next dev -p 3000 --turbopack --disable-source-maps.

bun run dev

Open http://localhost:3000 to see the storefront and http://localhost:3000/admin to see the admin. One process serves both.

Sign-in

The seed creates an admin account for admin@example.com. Enter that address at /auth/login and follow the link in the email. Sign-in uses a magic link. Outside production Litestore doesn't send email at all, so the email, including the link, is printed in the terminal running bun run dev.

Inbox
Sign in to Your StoreTo ava@example.com
now
YYour sign-in linkClick the button below to sign in. No password needed.Sign inDidn't ask for this? You can ignore this email.
You sign in by clicking the link Litestore emails to you.

Then open Settings → Developer. The Self-host readiness panel runs a live SELECT 1 against Postgres and a redis.ping(), each with a 3-second timeout. It also checks whether the site URL uses https, and whether Resend, S3, Stripe and an AI provider are configured.

If the panel reports Redis as down, check that the Compose services are running and that REDIS_REST_URL points at port 8079.

Troubleshooting

Env validation only checks that a variable is present, not that its value works. The readiness panel is the only step that actually calls the services.

Next steps

On this page