GrowGPT
AI commerce platform helping merchants follow high-intent traffic into ChatGPT and Google AI
/ Overview
The traffic that built e-commerce is migrating to AI platforms. GrowGPT helps merchants follow it — an Nx monorepo with seven apps shipping under one platform that lets shops reach customers on ChatGPT and Google AI.
See it live/ Project Details
Category: AI commerce SaaS
Engagement: In-house product — CraftWeb Labs
Role: Architecture, full-stack, AI integration
Timeline: 2026 — active
Live: staging.growgpt.app
/ Problem
Google Search delivers fewer clicks at higher cost. Meta Ads ROAS drifts. A generation of shoppers moved product discovery into ChatGPT, Gemini and Perplexity. ChatGPT-referred traffic converts 2× better than organic search — but every retailer with a Shopify or WooCommerce store is invisible at exactly the moment when discovery is happening. GrowGPT was started in early 2026 to be the missing layer.
/ TL;DR
7 apps
One Nx monorepo — dashboard, landing, widget, MCP server, MCP discovery, enrichment engine, Supabase.
37 edge fns
Supabase Deno Edge Functions powering real-time multi-tenant SaaS.
5 modules
FlowGuide, ShopScout, ProductGenie, DataFlow, ACP/UCP — all live behind one tenant config.
2× conversion
ChatGPT-referred traffic converts vs organic search (Similarweb 2025) — the data the platform bets on.
/ Vision
Five product modules behind a single tenant config, seven deployable apps in one Nx monorepo, multi-tenant SaaS enforced at the database. AI-native from day one — the MCP server lets agentic AI clients query the catalogue as first-class context.
/ Principles
One monorepo, many surfaces
Nx + pnpm holds dashboard, landing, widget, MCP server, discovery, enrichment and Supabase Edge Functions. Shared TS types, no version drift.
Multi-tenant at the DB
Supabase Row Level Security enforces tenant isolation at every query. Postgres rejects the read before it leaves the DB.
AI-native, not AI-bolted-on
Custom MCP server exposes catalogue + templates as MCP tools to ChatGPT/Gemini/Claude — no custom plugin per shop.
Five modules, one config
All modules live behind a single tenant config — one toggle reflects in dashboard, widget and Edge Functions.
/ Seven apps, one platform
Each app has one job and a clear contract. Nx dep graph keeps builds fast; shared packages keep types honest. No copy-paste between widget, dashboard and Edge Functions — one Supabase schema, one set of TS types, one source of truth.
/ Deployable units
web
Merchant dashboard — React 18 + Vite + Tailwind + shadcn/ui + JWT against Supabase.
landing
Marketing site SSG/ISR — Next.js 15 App Router + React 19.
widget
Embeddable IIFE bundle — React + esbuild + scoped CSS + XSS-sanitised.
mcp-server
Exposes catalogue + templates as MCP tools to ChatGPT/Gemini/Claude.
mcp-discovery
Routes AI-platform queries to the right merchant tenant.
enrichment-service
Node + Express + Drizzle. Pulls product feeds, enriches with Gemini, writes to Supabase.
supabase
Postgres + 37 Deno Edge Functions + Row Level Security + PLpgSQL migrations.
/ Engineering challenges
Shipping a multi-tenant SaaS in 90 days surfaces problems most monorepos never face: build-time env vars, XSS in customer-supplied CSS, dual-auth for cron and users. Every challenge below was solved with a single named commit. The fixes ship in production.
/ 01 — 04
01 — Landing into its own Next.js 15 app
Landing lived inside React/Vite dashboard, broke at 90 components. Fix: 513d2da — 108 files extracted into apps/landing with SSG/ISR, metadata API, hydration-safe theme toggle, Vercel rewrites so visitors still see one domain.
02 — Dual auth: API-key for cron, JWT for users
Scheduled imports need long-lived secrets; user-triggered imports need JWTs. Fix: 244df94 — Edge Function accepts either path; audit log records which was used per request.
03 — XSS-safe widget CSS injection
Merchants apply custom CSS to product carousel — naive <style> injection is a script-injection vector. Fix: ac050ed — sanitiser strips </style>, comment escapes, @import URLs, tag-like sequences; output wrapped in scoped shadow class.
04 — Scheduled imports + Gemini rate limits
First cron hit Gemini quota on a 10K-product feed. Fix: af92197 — Supabase scheduled Edge Functions (no external queue), per-tenant usage tracking, exponential backoff + full jitter on 429 (cap 60 s), batch size 10–20 rows.
/ More challenges
Build-time env-var crashes, dead third-party dependencies, three-tab UX that nobody could parse. The middle of a build is where the assumptions break — and where the case study earns its weight.
/ 05 — 08
05 — Build-time env vars vs runtime Supabase
Vercel build crashed: articles pages doing generateStaticParams + Supabase fetch with env vars missing during prerender. Fix: 31ef7a3 — articles forced to dynamic, Supabase client lazy-init (env checks on render not import).
06 — DataFlow: three tabs in, one flow out
Three tabs (Upload File / External Feed URL / Local XML) confused users; scheduling controls on only one tab. Fix: 6f29844 — single Scheduled Feed Imports flow with cron-builder UI; transport inferred from URL pattern.
07 — Removing GCS dependency nobody used
Early sketch included GCS; the actual flow ended on Supabase Storage. Fix: ea76397 — removed @google-cloud/storage, orphan UI field, dead enrichment paths. One storage layer, one bill, one set of credentials.
08 — Visual widget builder with live CSS preview
Merchants need to see widget before pasting embed snippet. Fix: 044cc65 — live preview renders the production widget bundle in an isolated iframe; same sanitiser as production. WYSIWYG that actually matches WYG.
/ Workflow
Merchant signs up, pastes a product feed URL into DataFlow, enrichment-service pulls the catalogue and Gemini fills missing fields. Data lands in Postgres scoped by tenant. Merchant enables modules, the dashboard generates a widget snippet, and the first shopper conversation streams within hours. In parallel: the MCP server makes the catalogue queryable by ChatGPT and Gemini agents natively.
/ 90-day build timeline
Phase 1 — Repo created
Early February 2026. Empty Nx + pnpm workspace, Supabase provisioned, Edge Functions skeleton, tenants table with RLS on day 1.
Phase 2 — First three modules live
FlowGuide + ShopScout + ProductGenie ship with backend Edge Functions, dashboard config and widget integration.
Phase 3 — DataFlow + enrichment
Self-hosted Node + Express + Drizzle. Gemini wired up, dual auth lands (244df94), DataFlow UX collapses from 3 tabs to 1 flow (6f29844).
Phase 4 — Landing extracted
Late February. Commit 513d2da (108 files), ThemeToggle hydration fix, build-time env-var crash fix (31ef7a3).
Phase 5 — Widget polish
Custom CSS sanitiser for XSS-safe injection (ac050ed); visual template builder with live CSS preview (044cc65).
Phase 6 — ACP/UCP + MCP layer
Early March. Commerce Pages + ChatGPT Apps integration; custom MCP server + discovery layer let AI platforms query catalogues natively; dead GCS dep removed (ea76397).
/ Stack
Two stacks: Vercel-deployed frontend (Next.js 15 + React 18/19 + Tailwind + shadcn) and Supabase-hosted backend (Postgres + Deno Edge Functions + Gemini + custom MCP). Nothing chosen for novelty. Each line has a reason.
/ Tech
Next.js 15 + React 19
Landing — SSG/ISR for SEO; dynamic article rendering avoids build-time Supabase fetches.
React 18 + Vite
Dashboard — interactive SPA with Vite HMR for fast dev, JWT auth against Supabase.
Nx + pnpm
Monorepo — 7 apps, 6 shared packages. Nx dep graph keeps builds fast.
Tailwind + shadcn/ui
Same primitives on landing + dashboard. shadcn = owned code in packages/ui.
Supabase (Postgres + RLS)
Multi-tenant enforced at DB. No app filters by tenant_id.
37 Supabase Edge Functions
Deno runtime — API surface for dashboard, widget and ChatGPT Apps. Zero cold starts.
Google Gemini API
~$0.075 per 1M input tokens. Structured-output mode for product fields. ~10× cheaper than OpenAI for this workload.
Custom MCP server
@modelcontextprotocol/sdk — domain-specific tools typed against the same Postgres schema as the dashboard.
/ Engineering decisions
Seven ADRs that shaped the platform. Each one has a why. If the why ever stops being true, the decision goes back on the table.
/ 7 ADRs
01 — Nx + pnpm monorepo over per-app repos
Shared types auto-generate from Supabase schema, no version skew between widget and dashboard.
02 — Separate landing (Next 15) from dashboard (React 18 + Vite)
Optimal tool for each surface; Vercel rewrites add ~5 ms latency, acceptable.
03 — Supabase over a custom Node API
Zero cold starts on Deno; RLS enforces tenant isolation at DB.
04 — Gemini over OpenAI for enrichment
~10× cheaper per-1M-tokens; quality good enough on structured product fields.
05 — Custom MCP server over off-the-shelf
Domain-specific tools typed against the same Postgres schema as the dashboard.
06 — Embeddable widget over iframe-only
Native-like interactivity, Shadow DOM scoping, XSS-sanitised CSS injection.
07 — Dual auth: JWT for users, X-Api-Key for cron
Cron-only secrets never leak through user sessions.
/ Results
Five modules in 90 days, an architecture a small team can actually ship and maintain. Live on staging; merchants onboard via a single product feed URL.
/ Numbers
7 apps, 6 shared packages
One Nx monorepo. An architecture that lets a small team ship 5 modules in 90 days.
37 Edge Functions
Multi-tenant API powering dashboard, widget and ChatGPT Apps.
2× conversion
ChatGPT-referred traffic converts vs organic search (Similarweb 2025) — the data the platform bets on.
800M+ weekly users
ChatGPT weekly active users in 2025 (OpenAI) — the discovery channel merchants are aiming at.