Back to Case Studies

E-Commerce & Integrations · Live Demo

Serverless E-Commerce Storefront

A self-initiated demonstration storefront built to show what a complete e-commerce platform looks like end to end — not a screenshot, a working application. It runs on serverless AWS infrastructure and covers the full shopping journey: catalog, variants, cart, checkout, accounts, and order history.

13
Products in catalog
Serverless
AWS architecture
Live
Working application
0
Real orders processed

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:

Next.js 16 (App Router) TypeScript AWS Lambda (container image) API Gateway Turso / libSQL Drizzle ORM SQLite FTS5 Auth.js Stripe Resend AWS CDK GitHub Actions

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 unoptimized rather 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.