Environment
Environment references with fromEnv(), the .env files Handoff reads, and every environment variable it uses.
fromEnv()
import { defineConfig, fromEnv } from 'handoff-app'
export default defineConfig({
runtime: {
registryConnection: {
url: 'https://registry.example.com',
accessToken: fromEnv('HANDOFF_REGISTRY_ACCESS_TOKEN'),
},
},
})fromEnv(name)refers to a variable.fromEnv(name, { default: value })adds a fallback.- In a JSON config, write
{ "$env": "NAME" }. - References resolve after profiles merge, so a profile can change one value and keep the others.
- Secret settings accept only a reference:
integrations.figma.accessToken,runtime.registryConnection.accessToken, the database URL, emailapiKeyandpassword, and AI connectionapiKey.
See Build-time and runtime values for which values a registry reads at request time.
.env files
- Handoff reads
.envfrom the directory where the command runs. - A selected profile also reads
.env.<profile>on top of.env. - A variable already set in the environment wins over both files, so
VAR=value handoff-app ...always works.
Fixed variables
Handoff always reads these names.
| Variable | Purpose |
|---|---|
HANDOFF_PROFILE | Config profile merged onto the base config |
HANDOFF_WORKING_PATH | Directory that holds handoff.config.ts. The default is the current directory. |
HANDOFF_LOG_LEVEL | debug, info, warn, error, or silent. The default is info. |
HANDOFF_LOG_SCOPES | Comma-separated log sources: handoff, vite, next. The default is all three. |
HANDOFF_LOGIN_NO_BROWSER | true stops login from opening a browser, like --no-browser |
HANDOFF_CREATE_ASSETS_ZIP_FILES | false skips the icon and logo zip files in fetch |
HANDOFF_SYNC_SECRET | Optional deployment-wide credential with read and write access. A workspace uses it only when it has no token and no login. |
AUTH_SECRET | Registry session-signing secret, at least 32 characters. Required by a registry. |
AUTH_URL | Canonical public registry URL, with the base path. Required by a registry. |
PORT | Standalone registry server port |
HOSTNAME | Standalone registry server bind hostname |
HANDOFF_AI_KEY_SECRET | Encrypts readers' AI provider keys, at least 32 characters |
HANDOFF_AI_CONNECTIONS | JSON array of AI connections, merged over the configured list by id |
Setting defaults
Each of these is the default fromEnv() name of a setting. To use a different name, set the
setting to fromEnv('YOUR_NAME').
| Variable | Setting | Purpose |
|---|---|---|
HANDOFF_FIGMA_PROJECT_ID | integrations.figma.projectId | Figma file ID for fetch |
HANDOFF_DEV_ACCESS_TOKEN | integrations.figma.accessToken | Figma personal access token for fetch |
HANDOFF_REGISTRY_URL | runtime.registryConnection.url | Registry URL of a connected workspace |
HANDOFF_REGISTRY_ACCESS_TOKEN | runtime.registryConnection.accessToken | Registry access token of a connected workspace |
DATABASE_URL | runtime.registry.database.url | PostgreSQL connection string. Required by a registry. |
HANDOFF_APP_PORT | app.ports.app | Workspace server port. The default is 3000. |
HANDOFF_WEBSOCKET_PORT | app.ports.websocket | Workspace live-reload port. The default is 3001. |
HANDOFF_OUTPUT_DIR | exportsOutputDirectory | Fetched output directory. The default is exported. |
HANDOFF_SITES_DIR | sitesOutputDirectory | Build output directory. The default is out. |
Keep the name HANDOFF_OUTPUT_DIR; the documentation app also reads it directly.
Variables you name yourself, such as the keys of a custom storage provider or an AI connection, are
not listed here. A registry build writes out/registry/README.md, which lists every variable that
build needs, with the names from your config.
Deprecated names
HANDOFF_CLOUD_URL and HANDOFF_CLOUD_TOKEN still work as fallbacks for HANDOFF_REGISTRY_URL and
HANDOFF_REGISTRY_ACCESS_TOKEN, with a deprecation warning. Rename them.