Configuration
Davaux is configured through a davaux.config.ts file at the root of your project. Use defineConfig from davaux/config to get full TypeScript autocomplete:
// davaux.config.ts
import { defineConfig } from 'davaux/config'
export default defineConfig({
// options here
})
Server options
export default defineConfig({
server: {
port: 3000, // default: 3000
hostname: '0.0.0.0', // default: 'localhost'
},
})
port— the TCP port the dev server and production server listen on. Can be overridden at runtime with--portCLI flag.hostname— bind address. Use'0.0.0.0'to listen on all interfaces (needed inside containers or when exposing to a LAN).
Build options
Options under build apply during davaux build and have no effect on davaux dev.
export default defineConfig({
build: {
minify: true, // default: true
},
})
minify— minify client-side JavaScript bundles (islands andsrc/client.ts) with esbuild. Enabled by default. Set tofalseif you need readable output for debugging a production bundle — source maps are always generated regardless.
Performance options
Options under performance control how the production server (davaux start) handles HTTP caching. None of these affect davaux dev.
All three are enabled by default — a freshly built app is optimally cached without any configuration.
export default defineConfig({
performance: {
assetCache: true, // default: true
staticCache: 3600, // default: 3600 (seconds), or false to disable
etag: true, // default: true
},
})
Asset cache
assetCache controls browser caching for the framework's own compiled assets: /_davaux/islands.js, /_davaux/client.js, /_davaux/styles.css, and the partial-updates polyfill.
When enabled (the default):
- A content-hash fingerprint is appended to each asset URL at server startup (e.g.
/_davaux/islands.js?v=a1b2c3d4). The hash changes automatically on every build, so browsers always fetch the latest version after a deploy. - Assets are served with
Cache-Control: public, max-age=31536000, immutable, allowing browsers and CDNs to cache them indefinitely — the changed URL from the next build acts as the cache-bust.
Disable this only if you manage your own asset URL strategy or a reverse proxy overrides cache headers:
export default defineConfig({
performance: {
assetCache: false,
},
})
Static file cache
staticCache sets the Cache-Control: public, max-age=N header on files served from your public/ directory. The default is 3600 (one hour).
export default defineConfig({
performance: {
staticCache: 86400, // 24 hours
},
})
Set to false to serve public/ files with no cache header at all — useful if a CDN or reverse proxy manages caching upstream:
export default defineConfig({
performance: {
staticCache: false,
},
})
ETag
etag enables ETag response headers and 304 Not Modified responses for HTML pages. When a browser revisits a page it already has, the server compares the content hash against the If-None-Match request header. If the page hasn't changed, a 304 is returned with no body — saving bandwidth on both sides.
This is transparent to users and handled automatically. Disable it only if an upstream layer (load balancer, CDN) already handles conditional requests:
export default defineConfig({
performance: {
etag: false,
},
})
Compression
compress enables on-the-fly compression of dynamic route responses and files served from public/. Brotli is preferred when the client supports it, gzip otherwise, deflate as last resort.
Default: false. Enable this when running without a reverse proxy. If you deploy behind nginx, Caddy, or a CDN that handles compression, leave this unset — letting the proxy compress is more efficient and avoids wasted CPU.
export default defineConfig({
performance: {
compress: true,
},
})
Pass an options object to control which encodings are offered or to override the default content-type filter:
performance: {
compress: {
encodings: ['gzip'], // gzip only — no brotli
filter: (ct) => ct.startsWith('text/') || ct.includes('json'),
},
}
See the Compression page for the full options reference.
Path aliases
The paths option mirrors TypeScript's compilerOptions.paths and lets you use short import aliases instead of deep relative paths:
export default defineConfig({
paths: {
'~/*': ['./src/*'],
'@components/*': ['./src/components/*'],
'@db': ['./src/lib/db.ts'],
},
})
With this configuration you can write:
import { Button } from '@components/Button.tsx'
import { db } from '@db'
Instead of:
import { Button } from '../../components/Button.tsx'
import { db } from '../lib/db.ts'
Make sure the same aliases are also defined in tsconfig.json under compilerOptions.paths so the TypeScript language server resolves them during development.
External packages
By default, Davaux bundles all dependencies with esbuild. Packages that use native bindings, CJS require(), or other patterns that cannot be bundled into ESM must be excluded:
export default defineConfig({
external: ['better-sqlite3', 'sharp', '@libsql/client'],
})
These package names are added to esbuild's external list alongside the built-in node:* and davaux exclusions. The packages are resolved at runtime from node_modules rather than bundled.
When to use this: If you see errors like
require is not definedorCannot find moduleat runtime, the package likely needs to be marked external.
Plugins
Plugins extend Davaux's build pipeline and route scanner. The primary use case is adding support for non-standard file types (like .mdx or .md pages):
import { defineConfig } from 'davaux/config'
import { mdx } from '@davaux/mdx'
import rehypeHighlight from 'rehype-highlight'
import remarkGfm from 'remark-gfm'
export default defineConfig({
plugins: [
mdx({
remarkPlugins: [remarkGfm],
rehypePlugins: [rehypeHighlight],
}),
],
})
A DavauxPlugin is an object with optional esbuild and scanner hooks that let you modify the build configuration and add custom route file patterns.
Static generation options
Options under ssg only take effect when running davaux static. They have no impact on davaux dev or davaux start.
export default defineConfig({
ssg: {
outDir: 'dist/static', // default: 'out'
trailingSlash: 'never', // 'always' (default) | 'never'
basePath: '/my-project', // path prefix for subdirectory deploys
notFound: true, // generate 404.html (auto when _error.tsx exists)
sitemap: { baseUrl: 'https://example.com' }, // generate sitemap.xml
},
})
See the Static Generation page for full details on each option.
Visual editor
The editor block opts in to the dev-only visual editor and inspector overlay. It has no effect in production builds.
export default defineConfig({
editor: {
enabled: true, // must be true to activate — disabled by default
badge: {
position: 'bottom-right', // 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left'
label: 'Inspector', // text shown on the floating badge
},
theme: 'auto', // 'auto' | 'dark' | 'light'
css: `
/* raw CSS injected into the editor frame */
`,
cssFile: './editor.css', // path relative to project root
},
})
enabled— must be explicitlytrue; none of the editor endpoints or scripts are exposed otherwise.badge.position— corner of the viewport where the floating badge appears. Default:'bottom-right'.badge.label— custom text on the badge button. Default:'Inspector'.theme— colour scheme for the editor UI.'auto'(default) follows the inspected page'sdata-themeattribute.css— raw CSS string injected into the editor frame's<style>tag for custom overrides.cssFile— path to a CSS file (relative to the project root) injected into the editor frame. Merged withcssif both are provided. The file is re-read on every request in dev mode, so changes apply without a restart.
See the Visual Editor page for full usage documentation.
Complete example
// davaux.config.ts
import { defineConfig } from 'davaux/config'
import { mdx } from '@davaux/mdx'
import rehypeHighlight from 'rehype-highlight'
export default defineConfig({
server: {
port: 4000,
hostname: '0.0.0.0',
},
build: {
minify: true,
},
performance: {
assetCache: true,
staticCache: 86400,
etag: true,
compress: true, // enable when not behind a reverse proxy
},
paths: {
'~/*': ['./src/*'],
},
external: ['better-sqlite3'],
plugins: [
mdx({ rehypePlugins: [rehypeHighlight] }),
],
ssg: {
outDir: 'dist/static',
sitemap: { baseUrl: 'https://example.com' },
},
editor: {
enabled: true,
},
})
App-level middleware (sessions, security headers, CORS) belongs in src/middleware.ts, not in the config file. See the Middleware page for details.