Self-Hosting

Self-hosting gives you full control over your data and billing while matching the hosted experience.

What you'll need

  • Convex CLI (npm i -g convex)
  • Access to secrets for the features you want: Groq (AI), Kernel (screenshots), Resend (email), Polar (billing)

Quickstart (local)

  1. Clone the repo and install dependencies:
bun install
  1. Start Convex dev and set up Better Auth defaults:
bunx convex dev

This creates a dev deployment and prints the CONVEX_SITE_URL and CONVEX_URL.

  1. Configure essential secrets:

Run these commands to set the minimum required secrets in your Convex dashboard:

# Security & Auth
npx convex env set BETTER_AUTH_SECRET $(openssl rand -base64 32)
npx convex env set SITE_URL http://app.teak.localhost:1355

# Optional: AI (if you want card processing)
npx convex env set GROQ_API_KEY gsk_...
  1. Create local env files:

Copy the Convex URLs from your dashboard into each app's .env.local. Each app uses a framework-specific prefix for the same two vars:

AppPrefix
apps/webNEXT_PUBLIC_
apps/mobileEXPO_PUBLIC_
apps/extension, apps/desktopVITE_PUBLIC_

See Detailed Environment Reference for the full variable list.

  1. Start the stack:
bun run dev

Production basics

When moving to production:

  1. Update SITE_URL in Convex to your public domain (e.g., https://app.yourdomain.com).
  2. Update the CONVEX_SITE_URL and CONVEX_URL in your client env files to point to your production deployment.
  3. Point your domain's SITE_URL to wherever you are hosting the Next.js app.
  4. Add email (RESEND_API_KEY) and billing (Polar) keys to Convex env if needed.
bun run build
bun run start

Detailed Environment Reference

Add these to your env files before running locally or deploying.

Backend (packages/convex/.env.local)

SITE_URL=http://app.teak.localhost:1355
BETTER_AUTH_SECRET=your-secret               # Better Auth security
KERNEL_API_KEY=token                         # Kernel Browser
GROQ_API_KEY=gsk_...                         # AI processing
POLAR_ACCESS_TOKEN=token                     # Billing
POLAR_ORGANIZATION_TOKEN=token               # Polar organization
POLAR_SERVER=sandbox                         # sandbox|production
POLAR_WEBHOOK_SECRET=secret                  # Polar webhooks
RESEND_API_KEY=token                         # Email service

Web (apps/web/.env.local)

CONVEX_DEPLOY_KEY=
NEXT_PUBLIC_CONVEX_URL=https://deployment.convex.cloud
NEXT_PUBLIC_CONVEX_SITE_URL=https://deployment.convex.site
TEAK_DEV_APP_URL=http://app.teak.localhost:1355   # Optional local override

Client Apps (apps/mobile, apps/extension, apps/desktop)

Mobile, Extension, and Desktop share the same base variables (use EXPO_PUBLIC_ prefix for mobile, VITE_PUBLIC_ for extension and desktop):

VITE_PUBLIC_CONVEX_URL=https://deployment.convex.cloud
VITE_PUBLIC_CONVEX_SITE_URL=https://deployment.convex.site
TEAK_DEV_APP_URL=http://app.teak.localhost:1355   # Optional local override
VITE_WEB_URL=https://app.yourdomain.com           # Desktop only; defaults to https://app.teakvault.com

API Gateway (apps/api/.env)

CONVEX_HTTP_BASE_URL=https://deployment.convex.site   # Required: Convex .site URL
CONVEX_UPSTREAM_TIMEOUT_MS=10000                      # Optional: upstream timeout in ms (default: 10000)
TEAK_DEV_API_URL=http://api.teak.localhost:1355      # Optional local override

The CONVEX_HTTP_BASE_URL must point to your Convex .site domain (the same value as NEXT_PUBLIC_CONVEX_SITE_URL in apps/web). The API gateway forwards all authenticated /v1 and /mcp requests to this URL.

Where to get the values

  • Convex URLs: Run bunx convex dev. It prints both CONVEX_URL (for the client) and CONVEX_SITE_URL (for the site/auth endpoint). You can also find these in the Convex Dashboard under "Settings" -> "Deployment".
  • Better Auth:
    • BETTER_AUTH_SECRET: Generate a random string (e.g., via openssl rand -base64 32).
    • SITE_URL: This is the URL where your Next.js app is running. Locally, it's http://app.teak.localhost:1355.
  • Optional Features:
    • GROQ_API_KEY: Get from Groq Console for AI-powered card processing.
    • KERNEL_API_KEY: Get from Kernel for automated link screenshots.
    • RESEND_API_KEY: Get from Resend for email verification and password resets.
    • POLAR_*: Get from Polar if you want to use the built-in billing system.