Mersi

Quickstart

Clone, configure, and run all three services locally in under 10 minutes.

Prerequisites

  • Bun 1.x (backend/ runtime)
  • Node.js 20+ (scraping/ service)
  • PostgreSQL 15+ or a Neon serverless connection string
  • Redis 7+ (default: redis://localhost:6379)
  • A Crossmint server API key
  • An OpenRouter API key

1. backend/ (Bun + Hono AI agent)

Clone and install

cd backend
bun install

Configure environment

cp .env.example .env

Set the three required variables at minimum:

DATABASE_URL=postgres://user:pass@localhost:5432/mersi
CROSSMINT_SERVER_API_KEY=sk_production_...
OPENROUTER_API_KEY=sk-or-...

See the full backend environment reference for all options.

Run database migrations

cd backend && bunx drizzle-kit migrate

Start the server

bun run dev

Server listens on http://localhost:3000 by default (PORT env var overrides).

Verify

# Liveness
curl http://localhost:3000/health

# Interactive OpenAPI docs
open http://localhost:3000/swagger

2. frontend/ (Next.js app)

Install dependencies

cd frontend
bun install

Configure environment

Create a .env.local file:

NEXT_PUBLIC_CROSSMINT_API_KEY=pk_staging_...

Start dev server

bun run dev

App runs on http://localhost:3000 (Next.js default). The next.config.ts proxies /api/* requests to the backend at port 3001 or whichever port is configured.

Install dependencies

cd scraping
npm install

Configure environment

NODE_ENV=development
APIFY_API_TOKEN=
REDIS_HOST=localhost
REDIS_PORT=6379
SUI_NETWORK=testnet

See scraping environment reference for the full list.

Start dev server

npm run dev    # NestJS watch mode (alias: nest start --watch)

Available Commands

backend/

bun run dev              # Dev server with watch mode
bun run start            # Production server
bunx drizzle-kit generate   # Generate migrations from schema changes
bunx drizzle-kit migrate    # Apply pending migrations
bunx drizzle-kit studio     # Visual DB browser (Drizzle Studio)
bun test                    # Run tests
bun run codegen             # Run Sui TypeScript codegen

frontend/

bun run dev      # Next.js dev server
bun run build    # Production build
bun run lint     # ESLint check
bun run gen:api  # Regenerate API types from OpenAPI spec

scraping/

npm run dev    # NestJS watch mode (alias: nest start --watch)           # NestJS watch mode
npm run build         # Compile TypeScript
npm run start:prod    # Run compiled output
npm test              # Jest unit tests

Configuration Toggles (backend/)

Two environment variables switch implementations at startup with no code changes:

VariableOptionsDefaultEffect
PRODUCT_SERVICEmock or scrapingmockUse mock product data or live Apify scraping via the scraping/ service
CART_SERVICEdb or onchaindbRedis-backed cart or Sui Move contract on-chain cart

When CART_SERVICE=onchain, you must also set SUI_CONTRACT_ADDRESS, SUI_CART_REGISTRY_ID, and SUI_RELAYER_PRIVATE_KEY. The server fails fast with a clear error if any are missing.

Testing the Chat Agent

A dev login endpoint is available in non-production environments:

# 1. Create dev session (sets crossmint-jwt cookie automatically)
curl -c cookies.txt -X POST http://localhost:3000/api/dev/login \
  -H "Content-Type: application/json" \
  

# 2. Complete onboarding step 1 (required before chat)
curl -b cookies.txt -X POST http://localhost:3000/api/onboarding/step-1 \
  -H "Content-Type: application/json" \
  -d '{"displayName":"Dev User"}'

# 3. Complete onboarding step 2
curl -b cookies.txt -X POST http://localhost:3000/api/onboarding/step-2 \
  -H "Content-Type: application/json" \
  -d '{"firstName":"Dev","lastName":"User","street":"123 Main St","country":"US","city":"New York","zip":"10001"}'

# 4. Complete onboarding step 3
curl -b cookies.txt -X POST http://localhost:3000/api/onboarding/step-3 \
  -H "Content-Type: application/json" \
  -d '{"topsSize":"M","bottomsSize":"32","footwearSize":"10"}'

# 5. Chat with the agent
curl -b cookies.txt -X POST http://localhost:3000/api/chat \
  -H "Content-Type: application/json" \
  -d '{"messages":[{"role":"user","content":"Find me a blue denim jacket under $100"}]}'

Or open the built-in test page at http://localhost:3000/test.

How is this guide?

On this page