Web + Mobile AI-assisted die-cut sticker design tool
Turn any artwork into a print-ready die-cut sticker: automatic background removal, contour generation, print-readiness checks, mockup preview, and a shareable storefront.
![]() |
![]() |
![]() |
![]() |
|
|
┌─────────────────────────────────────────────────────────────────┐
│ CLIENTS │
│ ┌──────────────────┐ ┌──────────────────────────┐ │
│ │ Next.js 16 Web │ │ Expo React Native Mobile │ │
│ │ (Vercel) │ │ (EAS Build) │ │
│ └────────┬─────────┘ └─────────────┬────────────┘ │
└───────────┼─────────────────────────────────┼───────────────────┘
│ GraphQL / WebSocket │ GraphQL / REST
▼ ▼
┌─────────────────────────────────────────────────────────────────┐
│ Go API (Cloud Run) │
│ gqlgen · Clerk JWT auth · R2 presigned URLs │
│ Redis pub/sub · asynq job dispatch · Gemini AI metadata │
└──────────────────────────┬──────────────────────────────────────┘
│ Redis (Upstash asynq)
▼
┌─────────────────────────────────────────────────────────────────┐
│ Go Worker (Cloud Run) │
│ core-imaging pipeline: │
│ BG removal → Moore contour → Douglas-Peucker + Chaikin → │
│ SVG CutContour → print-readiness report → mockups → export │
└──────────────────────────┬──────────────────────────────────────┘
│
┌─────────────────┼─────────────────┐
▼ ▼ ▼
┌────────────┐ ┌──────────────┐ ┌──────────────┐
│ Neon PG │ │ Cloudflare │ │ Upstash │
│ + pgvector│ │ R2 Storage │ │ Redis │
└────────────┘ └──────────────┘ └──────────────┘
Stack: Go 1.25+ + gqlgen · Next.js 16 App Router · Expo SDK 56 · React 19.2 · React Native 0.86 · Postgres + pgvector (Neon) · Redis/asynq (Upstash) · Cloudflare R2 · Clerk Auth · Google Gemini AI · Cloud Run · Turborepo
- Pure-Go imaging pipeline — background removal, contour tracing, and SVG cut-path generation with no OpenCV/cgo dependency; sub-10s on 2000×2000px artwork.
- Print-production correct — emits CutContour/KissCut spot-color layers (RasterLink/FlexiSign compatible) and validates DPI, 3mm bleed, safe area, and color gamut before export.
- Realtime by default — design processing status streams to web and mobile over GraphQL subscriptions (WebSocket), not polling.
- Type-safe across the stack — one GraphQL schema generates both Go resolvers (gqlgen) and TypeScript client types.
- Keyless CI/CD — GitHub Actions deploys to Cloud Run via GCP Workload Identity (OIDC, no long-lived keys); all runtime secrets live in GCP Secret Manager.
No hosted demo — this is a self-hostable system. Follow the Quick Start, then the full deployment guide.
# Prerequisites: Go 1.25+, Node 22+, pnpm 11+
# Clone and install
git clone https://github.com/karankashyap/diecutgo
cd diecutgo
pnpm install
# Configure environment (see DEPLOY.md §1 for where each key comes from)
cp .env.example .env.local
# Edit .env.local with your credentials
# Run DB migrations (requires golang-migrate)
make migrate-up
# Start all services (in separate terminals)
make api # Go API on :8080 (playground at /playground)
make worker # Go Worker — polls Redis for jobs
pnpm dev # Next.js web on :3000→ Full deployment guide (Vercel, Cloud Run, EAS, GCP setup, Secret Manager): DEPLOY.md
Run the entire backend locally with Docker — no Neon, Upstash, Cloudflare, Clerk, or Gemini account required. Postgres, Redis, and object storage (MinIO) run in containers; auth and AI degrade gracefully in development mode.
cp .env.local.example .env.local # already configured for the local stack
make dev-up # postgres + redis + minio, migrations + seed
make dev-api # Go API on :8080 (new terminal)
make dev-worker # Go worker (new terminal)Then exercise the full upload → pipeline → result flow from the GraphQL playground at http://localhost:8080/playground — no login needed (resolvers fall back to a seeded dev user via DEV_USER_ID). MinIO console is at http://localhost:9001 (minio / minio123).
No
make? The targets are thin wrappers:docker compose up -d --wait, thengo run ./services/apiandgo run ./services/worker. The web UI (pnpm dev) additionally needs a free Clerk publishable key for its sign-in components; the backend and pipeline are fully testable without it.
apps/
web/ Next.js Studio + Storefront
mobile/ Expo React Native capture + design
services/
api/ Go gqlgen GraphQL gateway
worker/ Go async image pipeline
packages/
core-imaging/ Go: BG removal, contour, readiness (the core)
graphql/ Shared GraphQL schema + generated TS types
ui/ Shared design tokens + shadcn components
jobs/ asynq job type definitions
infra/
migrations/ golang-migrate SQL files
cloudrun/ Cloud Run service YAML configs
The technical centerpiece. Pure Go library with sub-10s processing on 2000×2000px images:
- Background removal — Border sampling, adaptive alpha mask, morphological cleanup
- Contour tracing — Moore neighborhood tracing, Douglas-Peucker simplification, Chaikin smoothing
- SVG export — CutContour + KissCut spot color layers (RasterLink/FlexiSign compatible)
- Print-readiness — DPI (≥300 PASS), bleed (≥3mm PASS), safe area, color gamut checks
- Print export — Full SVG with 3mm bleed box, trim marks, embedded artwork, CutContour spot layer
| Pipeline | Trigger |
|---|---|
| Lint + typecheck + build | Every push/PR |
| Go tests + 60% coverage gate | Every push/PR |
| Playwright e2e smoke | Every push/PR |
| Docker build + Cloud Run deploy | Push to main |
| EAS mobile build | Tag v* or manual |
| Secret | Purpose | Where to get it |
|---|---|---|
GCP_WORKLOAD_IDENTITY_PROVIDER |
GCP OIDC keyless auth | See DEPLOY.md §4.7 |
GCP_SERVICE_ACCOUNT |
GCP service account email | See DEPLOY.md §4.7 |
GCP_PROJECT_ID |
GCP project ID | GCP Console → project selector |
GCP_REGION |
Cloud Run region | e.g. us-central1 |
EXPO_TOKEN |
EAS build token | https://expo.dev/settings/access-tokens |
All application secrets (DATABASE_URL, REDIS_URL, CLERK_, R2_, GEMINI_API_KEY, etc.) are stored in GCP Secret Manager and mounted into Cloud Run at deploy time. See DEPLOY.md §4.2 for the gcloud secrets create commands.
Gemini calls now time out instead of hanging indefinitely (services/api/internal/ai/gemini.go), and asynq job retries are idempotent — a redelivered job checks a processed_at fencing token before reprocessing, so it can't double-write storage or regress a design to a stale result (infra/migrations/000006_add_designs_processed_at.up.sql, services/worker/main.go). Covered by tests in services/api/internal/ai/gemini_internal_test.go and services/worker/main_test.go.
Open gaps:
- Background removal ignores the source image's existing alpha channel — dark artwork already on a transparent PNG can be absorbed into "background" and disappear.
packages/core-imaging/bgremoval.go. generateMetadataisn't wired into the web Studio UI yet — reachable via GraphQL, not called automatically once a design goesREADY.- No real per-token cost measurement against the live Gemini API;
services/api/cmd/costcheckgives a rough $/1000-designs estimate against a local model as a stand-in. - Default Gemini model (
gemini-1.5-flash) is stale relative to Gemini's current catalog. - Rate limiting is
NoopLimiter— no real per-user throughput cap. - Contour tracing is a convex-hull + Chaikin implementation; the architecture diagram above still describes it as Moore tracing + Douglas-Peucker.
- No real print shop or customer order has gone through this system yet.
MIT © Karan Kashyap




