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.
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.
| Requirement | What it does |
|---|---|
| Bun | Bun 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 newer | Install it locally or run it with the included compose.yml. |
| Redis or Upstash Redis | Every 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 bucket | Use 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. |
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 installbun 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 iconsBoth 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 psCompose 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:
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:deploydb: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:seedThis 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 devOpen 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.
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
Next steps
Configuration
env.ts requires some environment variables, leaves others optional, and each optional group turns on one service.
Development
Run Litestore day to day, reseed the database and run the checks before you commit.
Deploying
A configured store goes to production through migrations, the Next.js build and the Inngest functions.