Configuration items
This page details all configuration fields, types, default values and usage instructions of VextJS.
Configuration loading mechanism
VextJS uses a multi-layer configuration merging strategy, in order of priority from low to high:
The merged configuration is deep-frozen through deepFreeze() and cannot be modified at runtime.
Configuration file list
src/config/bootstrap.ts
When the database, key or configuration center patch needs to be injected before the configuration is frozen, you can add:
Constraints:
- provider must return plain object patch or
null - patch only supports JSON-like structure
- When
requiredis not declared:productiondefaults to fail-fast,development/testdefaults to continue after warning - In Cluster mode, the same provider patch will be reused in the same startup cycle to prevent Master / Worker from seeing different results.
Configuration file example
Complete configuration reference
VextConfig
host accepts "0.0.0.0", "::", an explicit IPv4 address, an explicit IPv6 address, or a hostname. With "::", the ready log prints IPv4 local URLs plus bracketed IPv6 local/network URLs such as http://[::1]:3000; explicit IPv6 hosts are printed with brackets too.
adapter
The underlying HTTP adapter supports three parameter passing methods:
trustProxy
When set to true:
req.ipreads the first IP from theX-Forwarded-Forrequest headerreq.protocolis read from theX-Forwarded-Protorequest header
This option needs to be enabled when deployed behind Nginx/cloud load balancer.
middlewares
Route-level middleware whitelist declaration. Only middleware declared here can be referenced in routes options.middlewares.
Global middleware (such as CORS, body-parser) is automatically registered by the framework and does not need to be declared here. Only routing-level optional middleware is declared here.
The first-party auth() helper is still registered as a route-level middleware file, then routes opt into protection with RouteOptions.auth:
VextCorsConfig
Cross-domain resource sharing configuration.
origins: ['*'] and credentials: true cannot be used at the same time. When you need to carry credentials, you must specify a specific domain name.
VextRateLimitConfig
Global rate limit configuration, implemented based on flex-rate-limit.
keyBy option
The routing level can override the global configuration via options.override.rateLimit, or set it to false to disable rate limiting.
VextRequestIdConfig
Request ID tracing configuration for log correlation and distributed link tracing.
requestId vs traceId
requestId is the unique identifier of the request built into vext, and traceId usually refers to the tracing ID generated by the APM link tracking system (such as OpenTelemetry / Jaeger). Both have different usage scenarios:
Mode 1: requestId acts as traceId (simple scenario)
Change the request header name of requestId to x-trace-id to unify it with the link tracking header, which is suitable for systems that do not rely on external APM:
Mode 2: requestId + APM traceId coexist (enterprise-level scenario)
Keep requestId (log association), and transparently transmit APM's traceparent header through config.fetch.propagateHeaders, suitable for connecting to OpenTelemetry / Jaeger and other systems:
- Internal system, simple tracing → Mode 1 (rename header to
x-trace-id) - Access OpenTelemetry / Jaeger / Datadog → Mode 2 (retain requestId, configure propagateHeaders)
- For details, see [Request context → Relationship with distributed tracing](/guide/request-context#Relationship with distributed tracing traceId) :::
Generators can also be replaced dynamically via plugins:
VextFetchConfig
Built-in HTTP client and request proxy configuration.
timeout must be a finite positive number no greater than 2147483647 milliseconds. retryDelay must be a finite non-negative number no greater than 2147483647 milliseconds, and function return values are validated at runtime.
VextFetchProxyTargetConfig
Proxy request header priority: target.headers < forwardHeaders < target.defaultInjectHeaders < options.headers < options.injectHeaders. Authorization does not transmit transparently by default, and both whitelist and allowAuthorizationForward: true must be configured.Agent retry priority: options.retry > target.retry > config.fetch.retry > 0. Only GET / HEAD / OPTIONS / PUT / DELETE will automatically retry when upstream 5xx or network error occurs; POST / PATCH does not retry by default, does not retry when timeout and returns local 504.
VextLoggerConfig
Structured log configuration, implemented by Vext's built-in logger kernel.
Log level priority (from high to low):
After setting a certain level, only logs of this level and higher will be output. Set to 'silent' to be completely silent.
The default logger also supports runtime app.logger.getLevel() / app.logger.setLevel(level) to adjust subsequent log thresholds; the configuration object itself will still be frozen after startup and should not be dynamically changed by modifying app.config.logger.level.
VextShutdownConfig
Graceful shutdown of configuration.
After receiving the SIGTERM / SIGINT signal, the framework will:
- Stop accepting new requests
- Wait for the in-flight request to complete (no more than
timeoutseconds) - Execute all
onClosehooks in LIFO order - Exit the process
VextServerConfig
Inbound Node.js HTTP server layer configuration. Applicable to built-in Native / Hono / Fastify / Express / Koa adapter, also applicable to development server created by vext dev. Unset fields retain the current Node.js default value.
config.server only controls inbound service requests. The timeout for outbound app.fetch / app.fetch.proxy is controlled by config.fetch.timeout, the proxy target timeout, or options when calling.
VextResponseConfig
Response format configuration.
Export packaging
When wrap: true is enabled, res.json(data) is automatically wrapped:
Error response format:
When wrap: false is disabled, res.json(data) sends raw data directly.
Hide internal errors
hideInternalErrors only affects the "unknown exception" 500 error path, such as the scenario where throw new Error("...") is directly used in routing, service, and middleware. It does not change the status code and response format of structured errors such as app.throw(...) or VextValidationError.
When hideInternalErrors: true is used, 500 errors are not exposed stack trace:
VextBodyParserConfig
Request body parsing configuration.
After disabled, req.body is always undefined, which is suitable for pure GET service or custom body parsing scenarios.
maxBodySize supported formats:
VextMultipartConfig
Multipart/File upload global configuration.
:::tip Fastify linkage
multipart.maxFileSize only limits the size of a single file; the total request body read limit is controlled by bodyParser.maxBodySize. When using Fastify, if fastifyAdapter({ bodyLimit }) is additionally passed in, the actual read boundary will be the smaller value of the adapter bodyLimit and the overall upper limit of body-parser.
VextAccessLogConfig
Access log configuration, implemented as onion-style after-middleware.
Access log output example:
Message fields include HTTP method, path, status code, response time (ms) and client IP; requestId is automatically injected into the JSON record field by logger's AsyncLocalStorage mixin.
VextOpenAPIConfig
OpenAPI documentation generation configuration.
docs.access.cacheKey is not a supported configuration field in this release. Vext rejects it to avoid implying response or access-result caching that the docs access pipeline does not currently provide.
For fixed local or deployed API targets, set servers[].url to the complete base URL including its port, for example http://127.0.0.1:3000. Use servers[].variables only for genuinely variable URL segments such as environment, region, tenant, or API version. docs.tryItOut.defaultServer controls the initial Try it out selection, while docs.tryItOut.customServer lets users temporarily enter another browser-side target without changing project config.
tagGroups is passed through as x-tagGroups only when explicitly configured. The default Vext Docs renderer builds recursive navigation from OpenAPI path segments; tagGroups is mainly for downstream OpenAPI tools that explicitly consume this vendor extension.
The default Vext Docs renderer derives Services / Utils / Models / Components / Plugins / Middlewares from code docs data. Model entries can show static schema fields, enums, options, indexes, methods, hooks, and usage. Plugins and middlewares can show inferred lifecycle/bootstrap, app extensions, middleware type, route usage, and source links. Locales, Config, Styles, and Preload are optional advanced static sources that can be enabled explicitly under docs.code; they are not shown in the default top-level documentation surface. Local loopback pages can also show Open source links for code docs entries without adding a separate configuration field.
guardSecurityMap legacy fallback
Automatically map routing middleware names to OpenAPI Security Scheme for legacy middleware-only routes. New Auth examples should prefer RouteOptions.auth through a local route guard helper so runtime protection and OpenAPI security share the same source:
securitySchemes
Supported security scheme types:
For apiKey schemes with in: "cookie" and for validate.cookie parameters, built-in docs can display the fields but browser Try it out cannot set the forbidden Cookie header directly. Use same-origin browser cookies or an HTTP client for manual cookie values.
VextRequestContextConfig
AsyncLocalStorage request context configuration.
:::warning After disabling, the following functions will be disabled:
- Logger automatically injects
requestId app.throw()automatically parses request-levellocaleapp.fetch()automatically propagatesrequestId:::
VextFrontendConfig
Built-in frontend build and static serving configuration.
Adapter extension contracts
frontend.adapter is an explicit, in-process typed seam; it is not automatic plugin discovery. A VextFrontendAdapter provides name, framework, and an optional resolveBuildOptions(config). The resolver receives the resolved frontend configuration and may return synchronous or asynchronous compiler options. It does not add another bundler, nor does it enable RSC, Server Functions, or PPR.
For a delivery target other than the built-in local staging adapters, pass a VextFrontendDeployUploadAdapter object to deploy.upload.adapter. It provides name and upload(input). Its VextFrontendDeployUploadAdapterInput contains asset, sourcePath, uploadKey, and dryRun; its VextFrontendDeployUploadAdapterResult must return uploaded and may return url and etag.
filesystem and mock are the only built-in upload adapter names. A provider-specific adapter stays explicit in application configuration, so the runtime does not silently install or discover cloud/bundler plugins.
By default spaFallback.scopes is empty, so unknown HTML paths are not swallowed into the SPA. For mixed SSR + client-router sub-apps, declare each basePath in scopes[]. spaFallback: true is kept only as a compatibility shorthand and is not recommended for enterprise mixed projects.
VextClusterConfig
Cluster multi-process configuration. For the complete interface definition, see src/types/app.ts VextClusterConfig.
Basic fields
healthCheck — heartbeat detection
reload — Zero-downtime rolling restart
cluster.reload only configures timing for rolling restarts triggered by vext reload / SIGHUP. Omitting cluster.reload does not disable rolling restart; Vext uses the defaults.
It can also be enabled through environment variables (no need to modify the configuration file):
VextCacheConfig
Route-level response cache global configuration.
Memory complete configuration:
Redis configuration:
MultiLevel configuration:
cacheHub only accepts response-cache-kit/cache-hub configuration and does not accept custom Store. Route-level response caching is configured via RouteOptions.cache. The public configuration unit is in milliseconds; the Cache-Control: max-age in the response header will output seconds according to the HTTP standard. See the Response Caching Guide for details.
VextDevConfig
Development-only configuration. These fields are read by vext dev and ignored in production.
VextDevOverlayConfig
DEFAULT_CONFIG
The full value of the framework’s built-in default configuration:
VextUserConfig
User-configured input type, all fields are optional. The complete VextConfig is generated by loadConfig() merging the default values.
VextSessionConfig
config.session.enabled: true auto-registers Session in production,
development, testing, and soft reload. The explicit session() middleware is
reserved for scoped/manual registration.
VextSessionCookieOptions follows CookieSerializeOptions and adds secure: boolean | "auto". Cookie options include domain, path, expires, maxAge, httpOnly, secure, sameSite, priority, partitioned, and encode.
VextSessionStore requires get(id), set(id, data, ttlSeconds), and delete(id). Optional methods are touch(id, ttlSeconds), clearExpired(), and close(). Vext calls close() during app shutdown for configured stores and active manual Session runtimes.
For cache-backed production sessions, prefer createCacheSessionStore(cacheLike, options?) from vextjs. It accepts a structural VextCacheLike with get, set, and del, converts session TTL seconds to cache milliseconds, stores JSON strings by default, and exposes close() only when options.close is provided. config.cache.cacheHub remains route response cache configuration and does not inject a Session Store.
RouteOptions.session accepts false, true, or { enabled?, rolling?, autoCommit? }. It can disable Session for one route or enable it while the global runtime is disabled.
VextCsrfConfig
config.csrf configures the built-in CSRF middleware. enabled: true auto-registers CSRF globally after body parsing and plugin global middleware. You can also keep it disabled and register csrf() manually for scoped paths.
Routes can opt out with route options { csrf: false }.
VextSecurityHeadersConfig
config.securityHeaders enables Vext's built-in browser security response headers. It is disabled by default. preset: "basic" is the low-impact path for most apps; strict and custom are explicit opt-ins.
basic sends X-Content-Type-Options: nosniff, Referrer-Policy: strict-origin-when-cross-origin, and X-Frame-Options: SAMEORIGIN. strict adds HTTPS-only HSTS, a minimal Permissions-Policy, COOP, and CORP, but still leaves CSP and COEP explicit. custom sends only fields you configure. Routes can opt out with { securityHeaders: false }.
loadConfig
Configuration loading function, receives the configuration directory path and performs the complete configuration chain merge.
Usually there is no need to call it manually, bootstrap() will automatically call loadConfig() internally. The merge order is: DEFAULT_CONFIG < default < config profile < local < bootstrap provider patch < CLI override.
Environment variable override
Some configurations support overriding through environment variables:
Type declaration extension
Plug-ins can add custom fields to VextConfig through declare module:
Later use in the configuration file will get full type hints: