veryfront.config.ts when a project needs
to deviate from those conventions.
Use environment variables for secrets and deployment-specific values. The
framework reads config and environment variables automatically.
Prerequisites
- A project created with
veryfront init(see Create project). - Write access to
veryfront.config.tswhen you need to override conventions. - Write access to the project’s
.envfile or deployment environment when you need secrets or deployment-specific values.
When to use config
Useveryfront.config.ts for stable project choices:
- Change directory conventions.
- Select app-router or pages-router mode.
- Change build output or trailing-slash behavior.
- Add a custom layout or app wrapper.
- Tune discovery paths for agents, tools, skills, prompts, resources, workflows, or tasks.
- Set project-level provider or MCP defaults.
- Protect application routes with declarative
security.auth.
security.auth declarative. Veryfront supports
function-valued config for general project configuration, but hosted auth should
resolve to a static Basic, Bearer, OIDC, or trusted-proxy shape. Do not put
provider clients, token verification code, network calls, or request-specific
auth logic in veryfront.config.ts. See
Application authentication.
Config file
defineConfig provides TypeScript autocompletion but doesn’t transform the
config. It is a pass-through for type safety.
Options
Project metadata
Directories
Override the default directory conventions:Router mode
Build
build.outDir must resolve to a child of the
project directory. Veryfront clears this directory before writing the build.
Use veryfront build --output <dir> when a one-off build must write outside the
project. The embedded preset does not clear its output root, so
build.outDir can resolve outside the project when you use
veryfront build --preset embedded.
Use serverExternalPackages for npm packages that must run only on the server,
such as database, cache, or messaging clients. Veryfront leaves these imports
external during server rendering so the runtime resolves the installed package
instead of sending it through the module CDN. If a declared package or one of
its subpaths reaches a browser transform, Veryfront stops with a
server-only-in-client error that names the import and source module.
When adopting this option, move shared imports behind a server-only boundary
first: for example, into server data hooks, API routes, or server components.
Declaring a package does not make it browser-safe and does not silently stub it.
Undeclared packages keep their existing browser-compatible resolution behavior;
Veryfront does not infer additional server-only packages from source code. Use
package roots only. Do not include versions or subpaths.
Layout
App wrapper
app to that project-local path.
React version
Experimental features
experimental.esmLayouts: false, remove that setting;
the false value is no longer supported. experimental.esmLayouts: true may
remain during migration, but is optional.
AI discovery
Control which directories are scanned for AI primitives:pathsare relative to your project root.- Defaults are
tools,agents,skills,prompts,resources,workflows, andtasks. - Set
enabled: falseto disable discovery for that primitive. - Eval, task, trigger, and workflow definitions with filenames containing
.test.or.spec.are ignored during discovery. Rename production definitions that use those filename segments before upgrading. - Discovery prefers a valid default export, then falls back to valid named
exports from the same module. A tool needs an
executefunction, an agent needs an agent definition, and so on. A plain helper module sitting in a discovery directory is not registered as a primitive. - Discovery still imports every candidate file in those directories in order
to inspect its default export, so any module-level side effects run at startup
even when nothing is registered. Keep shared helpers outside the discovered
directories, or narrow
pathsto the subdirectories that hold real definitions.
AI providers and MCP
Configure provider defaults or the app-facing MCP surface:Environment variables
Set secrets and deployment-specific values in.env files or your deployment
platform. Keep stable project structure in veryfront.config.ts.
Common groups:
- Cloud bootstrap:
VERYFRONT_API_TOKEN,VERYFRONT_PROJECT_ID,VERYFRONT_PROJECT_SLUG,VERYFRONT_API_URL, andVERYFRONT_PUBLIC_API_BASE_URLfor HTTPS inference gateway traffic when the control-plane URL is an internal HTTP service. - Agent services:
VERYFRONT_AGENT_SERVICE_NAME,VERYFRONT_AGENT_SERVICE_URL,VERYFRONT_AGENT_SERVICE_KEY,VERYFRONT_AGENT_SERVICE_REGISTRATION, andVERYFRONT_AGENT_SERVICE_REGION. - Provider keys:
OPENAI_API_KEY,ANTHROPIC_API_KEY,GOOGLE_API_KEY, and provider-specific base URLs. - Runtime:
PORT,NODE_ENV,REDIS_URL(backs the SSR transform cache, see SSR transform cache), request timeouts, SSR limits, andVERYFRONT_EXPERIMENTAL_RSC. - Observability:
VERYFRONT_OTEL,OTEL_TRACES_ENABLED,OTEL_METRICS_ENABLED,OTEL_EXPORTER_OTLP_ENDPOINT,OTEL_EXPORTER_OTLP_HEADERS,OTEL_SERVICE_NAME, and relatedOTEL_*values.
veryfront.config.ts files must not choose the
shared runtime OTLP endpoint, headers, service name, resource attributes, or
enable flags. Veryfront filters OTEL_* and VERYFRONT_OTEL from shared
runtime project env before request execution. Dedicated runtimes and local
development can use project/deployment OTEL_* values because they run in their
own process boundary.
Use Providers for model-provider setup. Use
Agent service runtime for the registration
variables used by standalone agent services.
Credentials and the API host
Averyfront.json apiUrl, and a VERYFRONT_API_URL or VERYFRONT_API_BASE_URL
set in a project .env file, point the CLI at a different API host. Both of
those files ship with a clone, so whoever wrote the repository chooses that
host. Veryfront never sends a credential you supplied yourself to a host the
repository chose: commands such as pull, merge, deploy, login, and
whoami refuse instead of authenticating.
To reach a self-hosted API host, pair the host and the credential from one
source:
- Put both
apiUrlandapiTokeninveryfront.json. - Or set both
VERYFRONT_API_URLandVERYFRONT_API_TOKENin the same project.envfile. A token that$NAMEexpansion copied out of your shell does not count as coming from the file, because the secret is still yours. - Or confirm the host yourself: set
VERYFRONT_API_URLin your shell for GraphQL commands, or setVERYFRONT_API_BASE_URLfor REST consumers such asdev,start,eval,styles build-artifact, and thevf_remote_*tools. Set the variable in the CI job environment to the API endpoint, including any base path it needs. Any credential then applies, including a CI secret and averyfront loginsession.
https://api.veryfront.com needs no confirmation, in any
equivalent spelling.
Veryfront blocks requests to hosts that resolve to private network addresses.
veryfront eval makes one exception: the API host you set in your shell with
VERYFRONT_API_URL or VERYFRONT_API_BASE_URL can resolve to a private address,
as a staging, VPN, or self-hosted API does. The exception covers only that exact
origin (scheme, host, and port). A host set in a project .env file or
veryfront.json does not qualify, and redirects stay rejected. For other
commands, add the origin to VERYFRONT_HOST_ALLOWED_INTERNAL_PROVIDER_ORIGINS:
VERYFRONT_API_TOKEN in the job environment whenever the project uses a
self-hosted API host, so a non-interactive run has a confirmed host. See
Deploy from CI for the surrounding workflow.
Provider stream idle deadline
Once a provider has sent its response headers, the body it streams back is bounded by an idle deadline. If no bytes arrive for the length of that window, Veryfront aborts the request, releases the connection, and fails the stream with a retryable error naming the deadline that fired. Without it, a model stream that went silent mid-response blocked its caller until the caller gave up.
The window is re-armed on every chunk, so it bounds how long the provider stays
silent rather than how long the whole response takes. It counts bytes on the
wire rather than parsed events, so a keepalive frame, an SSE comment line, or a
progress event re-arms it even when nothing decodes that event. That is what
keeps it from firing while a provider-executed tool such as web search or code
execution runs with the response held open.
Set it to
0 to disable the bound and restore an unbounded body, which only a
deployment that runs its own idle watchdog should do. A value that is not an
integer in range is ignored with a warning and the default applies; the warning
names the variable and the accepted range but never the rejected value, because
.env expansion can substitute a secret into it.
Set this one in the host environment, not in a project .env file. It is an
operator safety bound, so a value that came from a project .env file is
ignored and the host’s own setting stands.
Veryfront Cloud model routes
veryfront-cloud/* models call the platform’s vendor-neutral endpoints under
<api>/ai/v1: models that speak the OpenAI protocol use /chat/completions or
/responses, and models that speak the Anthropic protocol use /messages. The
request body names the
model as <provider>/<model>, for example anthropic/claude-sonnet-4-6.
Google models use the Gemini-compatible /ai/v1beta path, where the model is
named in the URL (/ai/v1beta/models/<model>:generateContent). A provider the
catalog serves on the Google surface under another name keeps its
provider-scoped route, so models with the same upstream id stay distinct.
The opt-out is temporary. It exists for one release so a deployment can move
back while it migrates, and a later release removes it. Any value other than
vendor keeps the vendor-neutral routes.
SSR transform cache
Veryfront compiles every page and its local import tree before it can render on the server. The compiled output goes in the SSR transform cache, so a route pays that cost once instead of on every request.Local development
veryfront dev keeps the transform cache on disk in the .cache directory of
the project it serves, including when you pass --project from another
directory. A restart reuses what the previous run compiled, so only files you
changed while the server was down are recompiled. This needs no setup and no
external service.
Cache entries are keyed by the Veryfront version, the project, the file path,
and a hash of the file contents, so an edit or an upgrade produces a new key
and never reuses stale output.
Run veryfront clean --cache to reset the cache. Deleting the project .cache
directory has the same effect. Both are safe: the next request recompiles what
it needs.
Set VERYFRONT_CACHE_DIR to keep the cache somewhere else. Set
VF_CACHE_BACKEND=memory to turn disk persistence off and keep the cache in
memory for the life of the process.
Deployed runtimes
SetREDIS_URL to back the SSR transform cache with Redis. Runtime instances
then share compiled output, so a new instance starts warm instead of
recompiling every route. Veryfront Cloud provides this cache for you, so
REDIS_URL matters only for self-hosted deployments. Self-hosting adds no
local dev requirement: REDIS_URL is unset by default and dev uses the disk
cache.
Release file cache tier
A deployed runtime reaches the distributed file cache once per key per request. Immutable release assets are held in a small process-local tier in front of it, so a warm asset costs no round trip at all. Only release-scoped keys are held. Branch-scoped content changes on every save and always reaches the backend. These variables tune that tier. The defaults are chosen to be safe, and every one of them is a bound rather than a performance dial, so raise them deliberately.
Set any of them to
0 to turn the tier off. VERYFRONT_FILE_CACHE_L1_TTL_MS=0
disables it outright; a zero byte or entry ceiling means nothing is ever
admitted. Values above 60000 for VERYFRONT_FILE_CACHE_L1_TTL_MS are clamped
to 60000.
The TTL is worth understanding before you raise it, because it bounds two
different things:
- Credential revocation. A held entry is served without asking the backend, which is where authorization is decided. So the TTL is the longest a credential revoked mid-flight can keep reading release assets of a project it was already authorized for.
- Cross-pod publish visibility. A publish invalidates this tier on the runtime instance that received the notification, and only that one. Every other instance keeps serving what it already holds until those entries expire. So the TTL is also the longest a publish can take to become visible everywhere. Raising it delays publishes on instances that did not handle the notification.
Environment-based config
UsegetEnv to read environment variables inside your config:
Reading config at runtime
The framework readsveryfront.config.ts automatically. Your config values are available to the build system and dev server. Pages and API routes access config indirectly through the features it enables (port, build output, router mode, etc.).
Verify it worked
After editingveryfront.config.ts, restart veryfront dev. The dev banner
prints the resolved title, output directory, and router mode. Set a
distinctive title and check that the document title in the browser matches.
For environment variables, set a temporary non-secret value such as
VERYFRONT_CONFIG_CHECK=enabled and read that value from a temporary API route.
Never return API tokens, provider keys, or other secrets from a route. Remove
the route and temporary value after confirming the configuration resolves.