Registry

Environment Variables

Registry-side and workspace-side environment variables.

Registry-side (required)

Set on the Vercel project or Docker host running the registry.

VariablePurpose
DATABASE_URLPostgres connection string. This is the switch — its presence is what puts getDataProvider() into registry mode (see Model). Auto-injected by Vercel Postgres.
AUTH_SECRETNextAuth session-signing key. Generate with openssl rand -hex 32.
HANDOFF_SYNC_SECRETBearer token for CLI push/pull and MCP (the legacy shared-secret credential, see API → Auth & scopes). Generate with openssl rand -hex 32.
AUTH_URLPublic production URL, needed by NextAuth for OAuth callback redirects. Required on Vercel.

HANDOFF_REGISTRY_MODE used to be listed here. It's inert on the current build path — only the deprecated vercel-build command reads it, and DATABASE_URL alone is what puts the app in registry mode.

Registry-side (optional)

VariablePurpose
HANDOFF_APP_BASE_PATHSub-path the registry is served under (e.g. design-system for example.com/design-system). Empty by default. It sets Next's basePath and is the most widely-read env var in the app — internal links, asset URLs and API paths are all built from it, so a sub-path deploy that omits it produces broken links throughout.
HANDOFF_DEFAULT_STACK_PROFILEDefault MCP stack-guide profile (e.g. bootstrap-handlebars, react-tailwind, tailwind-handlebars, react-scss) used for MCP project hydration before a workspace has pushed its own profile.
HANDOFF_PROJECT_NAMEDisplay name shown before any project config has been pushed.
HANDOFF_APP_URLPublic site URL used in password-reset / invite email links.
RESEND_API_KEYResend API key for sending invite/reset emails. Unset → those emails are logged only, never sent (fine for local/dev).
RESEND_FROMOptional verified sender address; defaults to Resend's onboarding domain in dev.
AUTH_GITHUB_ID / AUTH_GITHUB_SECRETEnables GitHub as a login provider, see Auth.
AUTH_GOOGLE_ID / AUTH_GOOGLE_SECRETEnables Google as a login provider.
AUTH_FIGMA_ID / AUTH_FIGMA_SECRETEnables linking a Figma account (API access, not login), see Auth.
HANDOFF_ADMIN_EMAIL / HANDOFF_ADMIN_PASSWORDNon-interactive alternative to the /setup UI, see First-admin setup.
HANDOFF_AI_API_KEYOpenAI key for AI features (pattern generation, design-to-component, vision). Omit if proxying AI through a remote HANDOFF_CLOUD_URL.
HANDOFF_AI_MODELModel for pattern generation/vision tasks. Defaults to gpt-4.1.
HANDOFF_AI_REQUEST_TIMEOUT_MSChat-completion timeout in ms. Default 180000.
HANDOFF_COMPONENT_GEN_MODEL / HANDOFF_VISION_MODEL / HANDOFF_REFERENCE_MODELModel overrides for design-to-component generation, vision comparison, and reference-material generation, respectively.
CRON_SECRETBearer the Vercel Cron job presents to POST /api/handoff/ai/design-jobs/run, the drain for queued AI design images. Unset means the route hard-fails with a 503 and queued images never generate, which is exactly how a demo deployment silently stalled. Generate with openssl rand -hex 32.
HANDOFF_CLI_JWT_SECRETSigning key for CLI sync JWTs (handoff-app login tokens). Optional, falls back to a value derived from AUTH_SECRET; set it only to rotate CLI tokens independently of sessions.

AI vars are about the design-to-component workbench, not MCP

The HANDOFF_AI_* / HANDOFF_COMPONENT_* / HANDOFF_VISION_* variables configure the registry's own AI-assisted design workbench (design artifacts → generated components), a separate feature from MCP, which doesn't call an LLM itself. See Concepts → Design artifacts.

Asset storage (optional)

Uploaded assets are stored in Postgres by default. Configure either backend below to offload them:

VariablePurpose
HANDOFF_S3_BUCKET / HANDOFF_S3_REGION / HANDOFF_S3_ACCESS_KEY_ID / HANDOFF_S3_SECRET_ACCESS_KEYAll four required together to enable the S3 asset backend; if any is missing, S3 is treated as unconfigured.
HANDOFF_S3_CDN_URLCDN origin to serve S3 objects from. Falls back to the bucket's own https://<bucket>.s3.<region>.amazonaws.com URL.
HANDOFF_CLOUDFRONT_DISTRIBUTION_IDCloudFront distribution to invalidate when an asset changes.
BLOB_READ_WRITE_TOKENVercel Blob token for design-artifact images. Unset (local dev / workspace mode) degrades gracefully — images stay inline instead of being offloaded.

Workspace-side (in the design-system repo)

VariableRequiredPurpose
HANDOFF_CLOUD_URLFor push/pullURL of the registry this workspace pushes to and pulls from.
HANDOFF_CLOUD_TOKENIf not using handoff-app loginBearer token — must equal the registry's HANDOFF_SYNC_SECRET.
DATABASE_URLNeverWorkspaces are filesystem-only. Setting this would switch the local app into registry mode, which is almost never what you want on a workspace machine.

After handoff-app login, the resulting JWT in .handoff/cli-auth.json takes precedence over HANDOFF_CLOUD_TOKEN, you can omit the token env var once logged in.

A handful of other workspace-side variables control config resolution and path layout (HANDOFF_WORKING_PATH, HANDOFF_FIGMA_PROJECT_ID, HANDOFF_DEV_ACCESS_TOKEN, …), see Workspace → handoff.config.* resolution for the full list.

On this page