Dev Server
vantris dev starts a native development server — Node.js node:http or Bun.serve, with no HTTP or WebSocket dependency. Both runtimes go through the same createDevServer(), so behaviour is identical under Node.js and Bun.
vantris dev # → http://localhost:3000What the dev server does
- Serves
index.htmlas the entry document, injecting the HMR client. - Transpiles
.ts/.tsxon the fly with esbuild — transform only, no bundling. Each module is served individually, so startup is instant and unaffected by app size. - Resolves bare imports through an on-demand dependency bundler into
node_modules/.vantris/deps/. CommonJS packages get real named exports, and subpath imports (react-dom/client) work. - Serves CSS —
import "./x.css"becomes a processed, style-injecting module; a<link>is served astext/css. See CSS. - Inlines asset imports — images, fonts, media,
wasm,txt,json. See Static Assets. - Drives Hot Module Replacement over a typed WebSocket protocol.
Configuration
Host and port live in the dev block; everything about the networking layer (HTTPS, proxy, CORS, SPA fallback, base) lives in server.
import { defineConfig } from "vantris";
export default defineConfig({
dev: {
port: 3000, // default
host: "localhost", // default
},
});Binding to your network
By default the server binds to localhost and is only reachable from your machine. Expose it on the LAN with --host:
vantris dev --host # all interfaces (0.0.0.0)
vantris dev --host 0.0.0.0
vantris dev --host 192.168.1.42When bound to a shared address, both a Local and a Network URL are printed on start.
The serving allowlist
Serving follows a Vite-style allowlist — this is a security boundary, not a convenience:
- Source modules come from
rootDir(/src/*). public/contents are served at/.- Everything else under the project root —
node_modules,package.json, lockfiles, config files — is not reachable.
So a stray fetch("/vantris.config.ts") in the browser returns a 404, and your secrets and tooling files never leak into a page.
Error overlay
When a module fails to transpile or a transform throws, the dev server pushes a type: "error" message over HMR and the browser shows a dismissable in-browser overlay with the message and location. It's cleared automatically on the next successful update — so you fix the file, save, and the overlay disappears with the applied change.
Dependency handling
The first time a bare import is requested, Vantris bundles that package on demand and caches the result. You never list your dependencies. Two options tune this:
export default defineConfig({
optimizeDeps: {
include: ["react", "react-dom/client"], // pre-bundle at startup
exclude: ["some-esm-only-lib"], // serve as native ESM
},
});Modules served from /@vantris/deps/ are marked third-party, so Chrome DevTools greys them out in Sources and skips them while stepping. See Dependency Pre-Bundling for the full model.
Networking features
The server block turns on HTTPS, request proxying, CORS, and the SPA fallback:
export default defineConfig({
server: {
https: true, // self-signed dev cert
proxy: { "/api": "http://localhost:8080" }, // proxy a prefix
cors: { origin: ["http://localhost:3000"] }, // CORS headers
spaFallback: true, // history fallback (default)
base: "/app/", // mount under a sub-path
},
});Each is covered on the Networking page and in the Server Options reference.
Plugins in dev
Plugin hooks run in the dev server just as they do in the build: resolveId/load/transform shape the module pipeline, transformIndexHtml rewrites the served HTML, handleHotUpdate customises HMR, and configureServer gives a plugin access to the running server. See the Plugin API.
Under the hood
The dev server never bundles your source in development — it transforms each module individually and lets the browser's native ES module loader assemble the graph. Dependencies are the exception: they're pre-bundled so you don't ship hundreds of node_modules requests to the browser. This "transform, don't bundle" model is why the dev server is fast regardless of how large the app grows.