Skip to content
Free shipping over $150

You are looking at a live demo

Every product, order and setting here is served by the bundled catalogue and stored in this browser. Nothing is shared between visitors, so you can change anything.

Back office
/admin — sign in with admin / admin
The contract, live
Run every read endpoint and see exactly what your own backend has to return.

Point it at a real API by setting two environment variables — the whole data layer swaps and no component changes. That is what the backend prompt is for.

LOOM documentation

A clothing storefront that runs on bundled demo data out of the box and on your own backend by changing one environment variable.

These pages are served by the storefront as well as by the repository: `/docs` on any deployment, prerendered and public. /docs/api adds an explorer that runs each read endpoint against whatever the shop is currently pointed at, so the response you read is the response you get.

Start here

If you want to…Read
Run it locally and look aroundQuick start below
Change the store name, menu, home page, currency[CONFIGURATION.md](CONFIGURATION.md)
Connect your own backend[API.md](API.md)
Take real payments[CHECKOUT.md](CHECKOUT.md)
Know the exact shape of every object[DATA-MODEL.md](DATA-MODEL.md)
Build your own database behind it[DATABASE.md](DATABASE.md)
Change colours, fonts, the logo[THEMING.md](THEMING.md)
Wire it to Odoo, Shopify, Medusa, WooCommerce[RECIPES.md](RECIPES.md)
Hand the whole spec to an AI and have it build the backend[INTEGRATION-PROMPT.md](INTEGRATION-PROMPT.md)
Have an AI design the database[SCHEMA-PROMPT.md](SCHEMA-PROMPT.md)
Understand the trust and conversion elements[CRO.md](CRO.md)
Run the back office, or build the write API[ADMIN.md](ADMIN.md)
Serve real traffic without melting[PERFORMANCE.md](PERFORMANCE.md)
Hand it to a merchant[USER-GUIDE.md](USER-GUIDE.md)
Understand an error you are seeing[ERRORS.md](ERRORS.md)

Three ways to run it

ModeDatabaseBackendUse when
mockNone — browser storageNoneDemos, design review, the public preview
apiSomeone else'sOdoo, Shopify, Medusa, WooCommerceYou already have a system of record
api + your ownThis schemaYou build it, from the promptsYou are building the commerce backend too

One environment variable moves between them. Nothing above src/lib/api/ knows which is running.

The documentation is also served inside the product, at /admin/docs — the same files, rendered, with copy buttons on every prompt and code block.

Quick start

bash
npm install
npm run dev          # http://localhost:5173

No database, no API key, no account. Twenty-four products, working cart, checkout and account, all in the browser.

The back office is at `/admin` — demo credential admin / admin.

How it fits together

text
  storefront ─┐
              ├─► src/lib/api/index.js ─► cache + dedupe + SWR
  /admin  ────┘        (one interface)          │
                                                │  VITE_DATA_SOURCE
                                    ┌───────────┴───────────┐
                                    ▼                       ▼
                                mock.js                  http.js
                          local database            fetch → your server
                          (src/lib/db.js)          + response validation

The admin panel and the storefront use the same interface, so an edit in one is visible in the other with no publish step. Reads pass through a cache that de-duplicates in-flight requests and serves stale-while-revalidating; writes purge only the namespaces they could have touched.

Nothing above src/lib/api/ knows which adapter is running. That is the whole design: build and demo against the mock, then point it at production without touching a component.

Alongside the data adapters sits a configuration document (GET /storefront) that drives identity, navigation, the home page, recommendations, currency and checkout. Between the two, almost everything a merchant would want to change is data rather than code — which is what makes an admin panel possible later without a rewrite now.

What is configurable without touching code

ThingWhere
Store name, tagline, logostore
Currency, locale, currency switcherpricing
Free-shipping threshold, shipping methods, countriescommerce
Wishlist / reviews / search / accounts / newsletter on or offfeatures
Header menu, submenus, footer columns, announcement barnavigation
The entire home page, as ordered typed sectionshome
Categories and sub-categoriesGET /categories
Fit, fabric, size chart, certificationsProduct.fit / .fabric / .sizeChart
Payment marks, trust toggles, honest-scarcity thresholdstrust

All of it is editable at `/admin`, which is also the reference implementation of the write API — see ADMIN.md. | "You might also like" strategy | recommendations | | Checkout mode and payment endpoint | checkout | | The reassurance strip | promises |

Full reference: [CONFIGURATION.md](CONFIGURATION.md).

Project layout

text
src/
  lib/
    api/index.js       the switch; asserts both adapters expose the same surface
    api/mock.js        bundled backend — catalogue, cart, orders, auth
    api/http.js        real backend — fetch, auth, response validation
    api/contracts.js   types and boundary validation
    config.js          every environment variable, resolved once
    money.js           integer minor units, formatting, discounts
    checkout.js        demo / redirect / api checkout modes
  data/
    catalog.js         demo products and categories (mock mode only)
    storefront.js      default configuration document
  store/               storefront, cart, wishlist, auth, toasts
  components/
    home/sections.jsx  the home page section registry
    ui/ product/ cart/ layout/ shop/
  pages/               one file per route
scripts/
  images.mjs           fetch, crop and grade photography; pins ids in a lockfile
  brand.mjs            favicons, app icons, OG card, manifest, robots
  sitemap.mjs          sitemap.xml

Commands

CommandWhat it does
npm run devDevelopment server
npm run buildBrand assets → production build → sitemap
npm run previewServe the build
npm run lintESLint
npm run imagesFetch any missing photography
npm run images:forceRe-roll every image
npm run brandRegenerate favicons, icons, OG card
  • TESTING.md — the suite, what it covers, and what it deliberately does not