Free and open source, cheaply hosted, Stripe-powered,
full-featured, limited-scope e-commerce platform.
staticart.org · npm · GitHub
Built with the Clearstack no-build web component specification. Ships as an npm package that scaffolds complete stores via Clearstack's platform stacking system.
flowchart TB
subgraph CDN["Static Site (CDN)"]
pages["Product pages"] ~~~ cart["Cart (localStorage)"] ~~~ spa["SPA (Hybrids.js)"]
end
subgraph API["Thin API (Lambda)"]
checkout["POST /checkout"] ~~~ webhook["POST /webhook"] ~~~ stock["GET /stock"]
orders["GET /orders"] ~~~ session["GET /session"]
end
subgraph DB["Database"]
dynamo["DynamoDB (single table)"]
end
CDN -- "checkout" --> API
API <-- "stock & orders" --> DB
dynamo -- "stock changed" --> rebuild["Build Trigger (GitHub Actions)"]
rebuild --> CDN
mkdir my-store && cd my-store
npm init -y
npm install @techninja/staticart
npm install -D @techninja/clearstack
npx clearstack init -y --static # Detects StatiCart, scaffolds store
npm install
npm run devEdit staticart.config.json to set your store name, then replace src/data/products.json with your catalog.
npm install
cd api && npm install && cd ..
npm run dev # Start dev server (port from .env.local)
npm test # Run tests (18 node + 31 browser)
npm run spec # Spec compliance checker (11/11)All store settings live in staticart.config.json:
{
"store": {
"name": "My Store",
"logo": "/assets/logo.svg",
"locale": "en-US",
"currency": "USD"
},
"shipping": { "type": "flat", "amount": 499 },
"tax": { "automatic": false },
"productFields": {
"isbn": { "type": "string", "label": "ISBN" },
"grade": { "type": "string", "label": "Condition" }
}
}store.name— displayed in the header (text fallback when no logo)store.logo— optional path to logo imageshipping.type—"flat","tiered", or"custom"(see docs)productFields— custom metadata fields rendered on product detail pages
Copy .env defaults. Override in .env.local (gitignored):
STRIPE_SECRET_KEY=sk_test_... # From Stripe dashboard
STRIPE_WEBHOOK_SECRET=whsec_... # From `stripe listen` CLIStatiCart is a Clearstack platform. Child projects get:
- Vendored components, store models, utils, and styles in
src/vendor/staticart/ - Config-driven branding, shipping, and product fields
- Override any component via import map specificity
- Override styles via CSS custom properties in
tokens.css - Override translations via
locales/overrides.json
See docs/app-spec/SCAFFOLD.md for the full override architecture.
node scripts/override.js molecules/product-cardThis copies the vendor component to src/components/ and patches the import map. Edit freely — your override is project-owned and never overwritten.
When developing StatiCart itself, sync source to the vendor directory before committing:
node scripts/sync-vendor.jsDefault language is English. To translate:
- Set locale in
staticart.config.json:{ "store": { "locale": "es" } } - Package translations live in
src/locales/<lang>.json(UI chrome only) - Project overrides in
src/locales/overrides.json(English) andsrc/locales/overrides.<lang>.json - Add custom keys for your own components in the override files
Cascade: package defaults → locale file → project overrides → project locale overrides.
The package translates framework UI (buttons, labels, status text). Store-specific
terms — category names, variant labels, product descriptions — are project data.
Define display names for your categories via category.<slug> keys in override files.
Variant labels come from products.json and are the store owner's responsibility.
Three shipping models:
- Flat rate — single fixed amount (
"type": "flat") - Tiered — rate tiers by cart subtotal with product classes and regional pricing (
"type": "tiered") - Custom — project-provided module at
api/lib/shipping-custom.js("type": "custom")
Static site: src/ → CDN (S3+CloudFront or Cloudflare Pages)
API: api/ → AWS Lambda via SAM:
cd api
sam build && sam deploy --guidedBuild pipeline: GitHub Actions rebuilds on stock changes:
node scripts/build-products.js # DynamoDB → dist/data/products.jsonSee docs/ for the full specification this project follows.
MIT