Skip to main content

Configuration

Use ev.config.ts for application-wide choices. Page-specific metadata, rendering, and plugin options belong in adjacent page.config.ts files.

ev.config.ts
import { defineConfig } from "@evjs/ev";

export default defineConfig({
routing: { mode: "spa" },
});

TypeScript configuration is recommended for completion and for typed page-plugin settings.

Top-level options​

OptionPurposeDefault
routingEnable file-based pages and select SPA or MPANot enabled until declared
conventionsEnable all framework file conventionstrue
devBrowser development serverPort 3000
loggingDevelopment logging, including browser-to-terminal forwardingBrowser errors forwarded
serverServer runtime, build resolution, and development serverBase path /__evjs, dev port 3001
transportBrowser-to-server originSame origin
targetProduction Android and iOS compatibility targetBundler default
polyfillExternal core-js source for an enabled targetBundled core-js
outputBrowser/server directories and asset CORS policydist/client, dist/server
pluginsInstall and configure integrations[]
bundlerSelect a non-default bundler adapterUtoopack from the CLI
applicationAdvanced explicit SPA route treeNot set

Routing​

Declaring routing enables the src/pages/**/page.* page tree:

export default defineConfig({
routing: {
mode: "spa",
basepath: "/next",
html: "./index.html",
mount: "#app",
},
});
FieldTypeMeaning
mode"spa" | "mpa"Required navigation/document model
basepathstringOptional SPA-only browser route prefix
htmlstringShared HTML template; defaults to ./index.html
mountstringReact mount selector; defaults to #app

The page root is fixed at src/pages. SPA and MPA read the same page files. See Pages and Routing for their capability differences. basepath is valid only for SPA routing. Page files, typed route paths, and navigation targets remain application-relative, while browser, development, SSR, and deployment paths receive the prefix. Omit it for a root-mounted SPA. The value must be an absolute, non-root static pathname such as /next.

Page configuration​

An optional page.config.ts sits beside a page.* file:

src/pages/profile/page.config.ts
import { definePageConfig } from "@evjs/ev";

export default definePageConfig({
title: "Profile",
meta: {
description: "View and update your profile.",
},
render: "ssr",
hydrate: "load",
plugins: {
analytics: { channel: "profile" },
},
});
FieldPurpose
titleStatic document title for the page
metaString map emitted as named <meta> elements
render"csr", "ssr", or "ssg"
hydrate"load" or "none" for explicit SSR/SSG pages
prerenderStatic or partial prerendering options
rscEnable RSC for an SSR page
document.aliasesAdditional .html or .htm output paths for a page-owned static document
pluginsStatic page options keyed by installed plugin id

The default export must be static JSON data. Read Rendering for valid render/hydration combinations and Using Plugins for plugin scope.

Development server​

export default defineConfig({
dev: {
port: 4000,
https: false,
cliShortcuts: true,
proxy: [
{
context: ["/backend"],
target: "http://localhost:8080",
pathRewrite: { "^/backend": "" },
changeOrigin: true,
secure: true,
},
],
},
server: {
dev: {
port: 4001,
https: false,
},
},
});

dev​

FieldTypeDefault
portnumber3000
httpsboolean | { key, cert }false
proxyDevProxyRule[][]
cliShortcutsbooleantrue

A proxy rule accepts context, target, optional pathRewrite, changeOrigin, and secure. The default Utoopack adapter supports boolean client HTTPS. Select the Webpack adapter when the client dev server requires a custom key/certificate pair.

logging​

logging.browserToTerminal follows the Next.js-compatible level contract and only affects ev dev with the Utoopack adapter:

ValueBrowser output forwarded to the terminal
"error"Errors and unhandled rejections (default)
"warn"Warnings plus errors
trueAll standard console levels
falseNothing

Set top-level logging: false to disable configurable logging. Essential CLI lifecycle output and fatal diagnostics remain enabled. The Webpack adapter does not currently implement browser log forwarding.

server.dev​

FieldTypeDefault
portnumber3001
httpsfalse | { key, cert }false

The server requires an explicit key/certificate pair for HTTPS. See Local Development for URLs, port fallback, and restart behavior.

Server​

export default defineConfig({
server: {
basepath: "/__evjs",
rsc: {
endpoint: "/__evjs/rsc",
},
resolve: {
alias: {
"server-sdk": "./src/server/sdk.ts",
},
},
externals: {
"native-addon": "commonjs native-addon",
},
},
});
FieldPurpose
basepathPrefix used for framework server-function, PPR, and RSC endpoints
rsc.endpointOverride the RSC Flight endpoint; does not enable RSC by itself
resolve.aliasModule aliases for server build entries only
externalsExternal module requests for server build entries only
devServer development port and HTTPS

basepath defaults to /__evjs. Keep the default unless a host or reverse proxy reserves it. Runtime paths must be absolute static URL paths; dynamic segments, wildcards, percent escapes, and ./.. segments are invalid.

Enable RSC in a page's page.config.ts, not in server.rsc.

Browser compatibility​

Set both minimum platforms to enable production syntax lowering and core-js:

export default defineConfig({
target: {
android: 6,
ios: 10,
},
});

The minimum accepted values are Android 5 and iOS 8. Both fields are required. This changes production browser output; it does not change Node.js or server compilation.

By default, targeted client entries bundle core-js/stable. To load an external UMD build instead, provide an absolute HTTP(S) URL:

export default defineConfig({
target: { android: 6, ios: 10 },
polyfill: {
coreJs: "https://cdn.example.com/core-js-bundle.min.js",
},
});

polyfill is valid only with target. It covers ECMAScript built-ins, not Web APIs such as fetch, AbortController, or Streams.

Output​

export default defineConfig({
output: {
client: "dist/public",
server: "dist/runtime",
crossOriginLoading: "anonymous",
},
});
FieldTypeDefault
clientproject-relative pathdist/client
serverproject-relative pathdist/server
crossOriginLoadingfalse | "anonymous" | "use-credentials""anonymous"

Client and server directories must be separate, non-nested descendants of dist and cannot contain empty, . or .. path segments.

Utoopack production builds name client JavaScript entries [name].[contenthash:8].js, additional JavaScript chunks [contenthash:8].js, and entry/async CSS [contenthash:8].css. Entry names distinguish pages; chunks and styles use short content-based names. Development uses [name].js and [name].css. These filename templates are framework defaults and do not require application configuration.

crossOriginLoading sets the crossorigin attribute for generated JavaScript and CSS tags and applies the same policy to dynamically loaded chunks.

Cross-origin server transport​

Same-origin applications need no transport configuration. When browser code must call an evjs server on another origin, set an absolute URL:

export default defineConfig({
transport: {
baseUrl: "https://api.example.com",
},
});

This configures framework browser-to-server calls, including server functions and the root api HTTP client. api preserves the complete baseUrl path prefix; page routing basepath is independent. Optional credentials (omit, same-origin, or include) and string-valued headers provide request defaults. Deployment defaults are overridden by application config, then by per-request options; headers merge case-insensitively. These settings are exposed to browser code, so do not put server secrets in them. Native fetch remains unchanged. See API Routes for usage.

Plugins​

Install plugins through factory calls:

import { analytics } from "@company/evjs-plugin-analytics";

export default defineConfig({
plugins: [
analytics({
endpoint: "/events",
debug: false,
}),
],
});

The factory argument is the plugin's application configuration. Conditional entries may use false, null, or undefined. Page-aware plugins expose their page contract under the plugin id in page.config.ts#plugins.

Application options and page options are separate contracts. They are not merged with each other. See Using Plugins.

Bundler​

The CLI selects Utoopack by default. Supply another adapter only when the application needs a capability or validation path it provides:

import { webpackAdapter } from "@evjs/bundler-webpack";

export default defineConfig({
routing: { mode: "spa" },
bundler: webpackAdapter,
});

Run ev inspect after changing the bundler. It reports capabilities required by the application's rendering choices.

Disable file conventions​

Applications that manage routing and runtimes themselves can disable page, API route, and middleware file discovery together:

export default defineConfig({
conventions: false,
});

There are no per-directory switches. conventions: false cannot be combined with routing. Imported "use server" modules and explicit application.routes remain available.

For the explicit SPA route API, read Custom Routing and Runtimes.