Ecommerce Template
Modern ecommerce template built with Next.js 16, React 19, Drizzle, Better Auth, Supabase, and Stripe.
Chat with a clerk and browse a 3D store to add items to your cart
AI summary · website content
CommerceJavaScript · CSSGitHub @amichael33OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗Talk to a clerk named Bob, then walk through a 3D store stocked with real products.
You tell Bob what you want ("a keyboard that sounds clicky, under $120"). He asks a question or two, searches Google Shopping and Amazon, and the store's shelves fill up with the results. Every product is a box with a funny price sticker on it.
Built at hackTX 26. Try it at stor3d.tech, watch the demo video and see our Devpost submission.
?map=castle (or classic, boutique, warehouse) links straight to a store.is_clothing), with garment words in the product titles as a backup; no extra API calls. Try ?demo=1 and ask for a hoodie: demo mode serves drawn demo garments (scripts/make-demo-clothes.mjs).public/js/maps.js: add an entry and it shows up on the start screen.npm install
npm start
Open http://localhost:3000.
No API keys? Open http://localhost:3000/?demo=1 for built-in demo products. Chat won't be smart without a Gemini key, but the store, boxes and stickers all work, and nothing spends credits.
With keys, create server/.env (copy server/.env.example):
GEMINI_API_KEY=... # chat, stickers, Try Next post-its
GEMINI_MODEL=... # optional, default gemini-3.5-flash-lite
SERPAPI_KEY=... # Google Shopping + Amazon + seller lookups
DEMO_MODE=0 # 1 = always serve demo products
PORT=3000 # optional
AMAZON_RESULTS=0 # optional: 0 turns Amazon off to save SerpApi credits
SEARCH_PAGES=2 # optional: pages per engine for the main query (1-3)
SEARCH_CACHE_HOURS=24 # optional: how long a search result is cached
Usage budgets (per visitor per day, plus a shared pool of SerpApi credits) are set with the BUDGET_* variables listed in server/.env.example.
The server reads .env only when it starts, so restart it after any change.
| Input | Action |
|---|---|
| WASD | Walk (during browsing) |
| Joystick (phones) | Drag the on-screen stick to walk; it only shows on touch devices while you can walk, and can be turned off on the start screen. Add ?joystick=1 to see it on a desktop. |
| Drag | Look around (works with a finger too, while a thumb holds the stick). A tap still selects a product |
| Click a box | Open its product card (price, store, rating, Buy, add to cart) |
| Click a sticky note | Search for that idea (asks first) |
| Esc | Close the card |
| Mic button | Tap to talk to Bob, tap again to stop; the text fills the box, you press Send |
| C | Show or hide the 3D cart |
| Walk up to Bob and type | Start a new search (your cart stays) |
| Buttons at the top | Arrange the store by price, rating, store or brand |
| Searches (top right) | Replay a past search; the cart tab lists your items |
browser (A-Frame / three.js) Express server outside
┌──────────────────────────┐ ┌───────────────┐
│ chat UI, mic, TTS │ ── /api/chat ──▶ │ clerk (LLM) │ ──────────────▶ Gemini
│ state machine │ ── /api/search ─▶│ search + cache│ ──────────────▶ SerpApi (Google Shopping + Amazon)
│ 3D store + product boxes │ ── /api/merchant▶│ seller lookup │ ──────────────▶ SerpApi (immersive product)
│ corkboard, replay │ ── /api/stickers▶│ sticker copy │ ──────────────▶ Gemini
└──────────────────────────┘ ── /api/ideas ──▶│ search ideas │ ──────────────▶ Gemini
── /api/geocode ▶│ geocode, img │ ──────────────▶ OpenStreetMap Nominatim
── /api/img ────▶└───────────────┘
The page moves through phases: INTRO → LOCATION → CHATTING → SEARCHING → OPENING → BROWSING.
ready: true), with optional price limits and up to 2 related searches.public/js/layoutStore.js) puts each product in a slot of the chosen map's shelves (maps.js describes the room; sceneMap.js builds it; collide.js gets its footprints from it). The boxes pop in one by one.| Route | Purpose | Limit / min |
|---|---|---|
GET /api/health | Liveness check | none |
POST /api/chat | One clerk turn: reply plus search query when ready | 30 |
POST /api/search | Google Shopping + Amazon products for a query | 10 |
POST /api/merchant | The seller's own page for a Google Shopping product (1 credit, cached) | 15 |
POST /api/stickers | Funny sticker text for a list of products | 30 |
POST /api/ideas | Follow-up search ideas for the corkboard (Gemini only) | 10 |
POST /api/geocode | GPS coordinates to a city name | 10 |
GET /api/img?u= | Image proxy for product thumbnails (allowlisted hosts only) | 300 |
public/vendor/), plain ES modules, Web Speech API and SpeechSynthesis. No build step, and no outside scripts or fonts, so it works on bad venue Wi-Fi.express-rate-limit, dotenv.google_shopping, amazon and google_immersive_product engines, OpenStreetMap Nominatim for reverse geocoding.public/ static site: index.html (start screen + the 3D scene), favicon.svg, css/ui.css
js/ state store, layout, maps, UI, voice, cart, saved searches, store colors
js/components/ A-Frame components: shelf, clerk, product-box, corkboard, alligator, ...
vendor/ A-Frame and the fonts, served locally
server/
index.js entry: loads .env, wires keys into the app
app.js Express app and all routes
lib/ clerk, serp, merchant, ideas, stickers, geocode, llm, cache, budget, env
data/ demo products and demo garments
test/ node:test suites (npm test)
scripts/ prewarm.js (caches the demo queries, uses real SerpApi credits), make-demo-clothes.mjs, check-maps.mjs
deploy/ deployment kit (see deploy/README.md)
docs/ ROADMAP.md (the current to-do list), superpowers/ (design specs and the build plan)
npm test
Pure logic (state, layout, maps, tiers, cutouts, cart, saved searches, store colors) and every API route are covered, with a fake fetch so no test spends SerpApi credits. The 3D scene and browser APIs are checked by hand. npm run check:maps drives a browser through every map; it is slow, so run it on a spare machine or CI, not a dev laptop.
Caddyfile serves public/ and proxies /api/* to the Node server on port 3000, and ecosystem.config.cjs runs the server under pm2 with NODE_ENV=production. In that mode Express binds to 127.0.0.1 and no longer serves static files, so Caddy has to be in front. Replace yourname.tech in the Caddyfile with the real domain.
SEARCH_PAGES=1 or AMAZON_RESULTS=0 to spend less. Gemini calls are separate.SERPAPI_KEY, in DEMO_MODE, past a daily limit, or if SerpApi fails, you get built-in demo products, and Bob says so.