Tinycrate is a multi-tenant e-commerce platform that runs entirely on
Cloudflare Workers and D1. Each merchant gets a storefront on a subdomain
(or a custom domain), an admin interface, Stripe-powered checkout with
subscriptions and refunds, UPS shipping labels, and passwordless
magic-link authentication. A native macOS merchant app talks to the same
backend through a versioned REST API described by a single OpenAPI
contract (openapi.yaml).
One Worker (src/index.js, built on Hono) routes by
hostname:
tinycrate.net— landing page and waitlist (src/routes/home.js)admin.tinycrate.net— merchant admin interface (src/routes/admin/)api.tinycrate.net— Stripe webhooks, storefront APIs, and the versioned/v1REST API (src/routes/api.js,src/routes/api/v1/)<shop>.tinycrate.netand custom domains — tenant storefronts (src/routes/tenant.js)
routes/— HTTP handlers, grouped by host.routes/admin/orders/splits the order workflows (detail, fulfillments, refunds, receipts, shipping labels, subscriptions).routes/api/v1/is the bearer-token API consumed by the macOS app: reads, writes, order operations, media ingest, pagination, and auth middleware.services/— business logic with no HTTP concerns: order, refund, fulfillment, inventory, and subscription services; Stripe Connect; UPS shipping (rates, labels, international, billing safeguards); Cloudflare API client for custom-domain provisioning; event logging.middleware/— CORS (separate policies per host class), CSRF, customer auth, order validation.views/— server-rendered HTML for the admin, tenant storefronts, customer subscription pages, and transactional emails. HTMX drives interactivity; there is no client-side framework.utils/— shared helpers: currency, dates, HTML escaping, markdown, encryption at rest, refund math, inventory claims, magic links, Stripe subscription sync.
- D1 (SQLite) — the primary database. Schema in
schema.sql, incremental migrations inmigrations/andmigrations-wrangler/. - R2 — media storage (
SITESbucket). - KV — revocable merchant sessions (
SESSIONSnamespace). - Email — Cloudflare
send_emailbinding for magic links, receipts, and subscription notifications. - Stripe — checkout, webhooks (platform and Connect), recurring subscriptions, and refunds. Merchants onboard through Stripe Connect.
- UPS — shipping rates and label generation, with billing safeguards and international shipment support.
Checkout, subscription, and refund flows are driven by Stripe webhooks handled on the API host. Inventory deduction is exactly-once (claim and release, so webhook retries no-op), and refund IDs are deterministic so concurrent submissions collide into an atomic no-op.
Passwordless magic links for merchants and customers. Merchant sessions
are opaque revocable tokens in KV; the /v1 API uses bearer tokens.
- Install dependencies:
npm install - Copy
.dev.vars.exampleto.dev.varsand fill in your Stripe, UPS, and Cloudflare values. - Replace the
REPLACE_MEplaceholders inwrangler.tomlwith your own Cloudflare account, D1 database, and KV namespace IDs. - Set up the database:
bash scripts/setup-db.sh(or applyschema.sqland a seed file withwrangler d1 execute). - Run locally:
npm run dev(startswrangler devplus a Stripe webhook listener). - Deploy:
npm run deploy. Production secrets are set withwrangler secret put(seescripts/setup-secrets.sh).
Tests: npm test. Type checking: npm run typecheck.
Further documentation lives in docs/.