A complete, production-shaped e-commerce storefront — built with Vite + React + TypeScript, no CSS framework, no backend required. It's the example app that ships with Adminium: browse a catalog, configure product variants, personalize items, run a cart with promo codes and a 4-step checkout, and place a (demo) order — all from built-in demo data.
Live demo → adminium.dev/demo/ecommerce-storefront
- State-based routing (no router) — a single
viewvalue drives the whole app: home, listing, product, cart, checkout, confirmation, and account. - Real commerce logic — a variant matrix with cross-option disabling and
out-of-stock overlays, composite cart line-items (options + engraving +
bundle),
WELCOME10promo, free-shipping progress, tax, and shipping tiers. - Light / dark themes via CSS custom properties, persisted to
localStorage. - Real product photography — every product, and the home hero, renders a
real photo (
object-fit: cover, lazy-loaded, with the product tint showing behind it while it loads). Self-hosted Manrope + JetBrains Mono and tree-shakenlucide-reacticons round out the visuals. - No payment integration — the checkout's card field only mimics Stripe Elements. Nothing is ever charged.
npm install
npm run devThen open the URL Vite prints (default http://localhost:5173).
-
Vercel — click the button above, or import the repo. Build command
npm run build, outputdist. -
DigitalOcean App Platform — click the button above, or use the included
.do/deploy.template.yaml. -
Host anywhere —
npm run buildproduces a fully staticdist/you can drop on any static host (Netlify, Cloudflare Pages, S3, GitHub Pages…). Or build the container:docker build -t ecommerce-storefront . docker run -p 8080:80 ecommerce-storefront
| Script | What it does |
|---|---|
npm run dev |
Start the Vite dev server. |
npm run build |
Type-check + build to dist/ at base / (root deploys). |
npm run build:demo |
Build to dist/ at base /demo/ecommerce-storefront/ (Adminium demo). |
npm run preview |
Preview a production build locally. |
There are two tiers to running this store.
Tier 1 — the frontend, one click. The Vercel / DigitalOcean buttons above deploy the storefront on its own, running on the bundled demo catalog (now with real product images). No database, no admin — a fully static preview.
Tier 2 — the whole stack, one command. docker-compose.yml
stands up Postgres (seeded by default with the same catalog, prices, and
images), an auto-generated Adminium admin dashboard that manages the catalog and
orders on that real database, and the storefront:
cp .env.example .env # then set ADMINIUM_SECRET — e.g. openssl rand -hex 32
docker compose up- Storefront → http://localhost:8080
- Adminium admin dashboard → http://localhost:4600
On first boot, shop-db applies db/schema.sql, installs the
demo bookkeeping from db/demo-toolkit.sql, and then runs
db/init-demo.sh, which loads db/seed.sql
unless you set DEMO_DATA=0. Adminium imports the shop database as its first
source connection, introspects the schema, and generates the admin dashboard.
Finish the ~1-minute first-run wizard at :4600 — it's pre-pointed at the shop
DB. With the demo data loaded, the storefront and the dashboard are the same
shop: the 16 products, their prices, and their images match one-for-one. The
install spec Adminium reads to configure itself is manifest.json.
The shop arrives stocked — the 16 products, their categories, the customers and
the order history all come from db/seed.sql. To start with an empty shop
instead, same schema and no rows, set DEMO_DATA=0 in .env before the first
docker compose up. Neither choice is permanent: the demo rows can be loaded
and removed again whenever you like.
| Script | What it does |
|---|---|
npm run demo:status |
What is loaded right now, table by table. |
npm run demo:import |
Load db/seed.sql. |
npm run demo:wipe |
Remove the demo rows — schema and your own rows stay. |
npm run demo:reset |
Wipe, then import a fresh copy. |
A wipe deletes only the rows a ledger attributes to the seed, so the products
and orders you added yourself, and the tables themselves, survive it. A demo
row your own data depends on is kept rather than force-deleted, and reported
under kept. ON DELETE CASCADE still applies, though: a demo order takes
its line items with it, including one you added yourself, and those are
counted separately as cascaded. wipe and reset ask before they act;
npm run demo:wipe -- --yes skips the question, which is what you need in a
script — without a terminal it fails rather than asking. Setting
DATABASE_URL points all four commands at a Postgres somewhere else — Neon,
Supabase, RDS — instead of the shop-db container.
db/README.md has the rest.
All catalog access goes through a thin DataSource interface
(src/data/source.ts) with a single demoSource
implementation backed by the bundled catalog. Once Adminium's browser-safe
publishable key ships, the frontend will read live data — your real
products, orders, and reviews from the database above — through the Adminium
records API via a second DataSource implementation, without touching any of the
screens or the store. The seam is already in place.
src/
app/ App shell + view switch
state/ Zustand store (cart engine, filters, checkout, theme)
data/ demo catalog, types, DataSource seam
lib/ pricing, ratings, placeholders, formatting
screens/ Home · Listing · Product · Cart · Checkout · Confirm · Account · NotFound
components/ Header, Footer, ProductCard, CartDrawer, OptionPicker, modals, …
styles/ tokens.css (design tokens) + base.css (fonts, utilities)
public/fonts/ self-hosted Manrope + JetBrains Mono (woff2)
db/ schema, demo seed + the demo-data toolkit (see db/README.md)
AGPL-3.0 © 2026 Ecommerce Storefront. A demo shipped with Adminium.
The Adminium skills teach Claude Code, Codex and other agents to build and change an app:
npx skills add Adminiumjs/skills — https://github.com/Adminiumjs/skills