Why We Built This
Static screenshots and a homepage full of adjectives can't show what a business actually gets when they hire us to build an e-commerce platform. So instead of another mockup, we built a real one: a working storefront with a full product catalog, inventory-aware variants, authenticated customer accounts, and a complete checkout flow — deployed the same way we'd deploy it for a client, on serverless AWS infrastructure.
This is a demonstration environment. Sample products and sample orders only — no payment is ever processed, and nothing here represents a real client engagement.
What It Demonstrates
- Product catalog and categories — 13 products organized into browsable categories, with sorting and featured/sale merchandising.
- Variants, pricing and inventory — per-variant stock levels and pricing, with detailed product specifications.
- Cart and checkout workflow — a full add-to-cart through checkout path.
- Customer authentication — account creation and login.
- Order history and status — a customer-facing order-status area.
- Product search and sorting — catalog-wide search with sortable results.
- Ratings and reviews — customer reviews with related-product recommendations.
- Responsive storefront — built to work across desktop and mobile.
- AWS serverless deployment — fronted by API Gateway, scaling without a fleet of servers to manage.
The storefront is built for "Acme Widgets," a fictional precision-widget manufacturer — a deliberately generic product line so the focus stays on the platform, not the props.
Architecture
The app is Next.js 16 (App Router, TypeScript, Tailwind), packaged as a container image and deployed as a single AWS Lambda function via OpenNext, fronted by an API Gateway HTTP API custom domain:
Data lives in Turso (libSQL, SQLite-compatible) via Drizzle ORM,
with a SQLite FTS5 index powering catalog search. Authentication runs on
Auth.js with credentials and JWT sessions, and guest checkout is supported
for shoppers who'd rather not create an account. Checkout itself is Stripe's
embedded Payment Element, and order confirmations go out through Resend.
Infrastructure is defined in AWS CDK (TypeScript), and GitHub
Actions runs lint, typecheck, tests, and a Docker/CDK synth on every pull request,
deploying on push to main.
The hosting path currently runs without a CDN: the single Lambda serves the Next.js SSR
output and its static assets directly through API Gateway, rather than through
CloudFront and S3. That AWS account's earlier verification gate — which had blocked
CloudFront and public Lambda Function URLs — has since cleared, so adding a CDN layer is
now a straightforward next step rather than a blocked one; it's a contained change to
infra/lib/acme-widgets-stack.ts.
The custom domain, demo.lighthouseconsult.com, is DNS-managed outside this AWS
account, so it's wired up with manual CNAME records rather than Route 53 automation — which
is also why the domain can take a little while to propagate after a fresh deploy. Until it
does, the same application is already live at its API Gateway URL.
Engineering Trade-offs
Built to demonstrate the platform end-to-end, not to gold-plate every operational detail — here's how we'd scope up the surrounding infrastructure for a production client engagement:
- Product images are pre-sized and served
unoptimizedrather than through a dedicated image-optimization function. - No incremental static regeneration — dynamic routes render per-request rather than being cached and revalidated.
- Production hardening: client deployments can add Secrets Manager, CloudFront edge caching, managed image optimization, enhanced monitoring, and environment-specific security controls based on operational requirements.
This Lambda has normal outbound access for its Stripe and Resend calls. For a harder version of the same problem — Stripe checkout from a Lambda function with no outbound internet at all — see how we solved that for a real WooCommerce store without paying for a NAT Gateway.
Two more posts dig into this storefront specifically: what it actually costs compared to Shopify, and how its product search runs on SQLite FTS5 instead of a paid search vendor.