DocsConfiguration
Configuration API
Configure Lunx with a single TypeScript file. Full autocomplete, type safety, and zero-config defaults for every field.
Rust core, lean install
lunx-dev is 1.1 MB. Bundling (Rolldown) and compiling (Oxc) run in Rust, installed with the package, so there is no separate native download.Minimal config (recommended)
typescriptlunx.config.ts
import { defineConfig } from 'lunx-dev' export default defineConfig({ framework: 'react', // optional if auto-detected entry: 'src/main.tsx', port: 5173, })
Common short options
| Field | Type | Default | Description |
|---|---|---|---|
| framework | 'react' | 'vue' | 'svelte' | 'solid' | 'preact' | 'lit' | 'alpine' | 'qwik' | … | — | Usually auto-detected. Meta-frameworks (SvelteKit, Nuxt, Remix, Astro…) are built by lunx; Next.js, Docusaurus, Gatsby, RedwoodJS and Stencil run their own CLI. |
| entry | string | string[] | — | App entry. Default often src/main.tsx. |
| outDir | string | 'dist' | Production output folder. |
| port | number | 5173 | Dev server port (also server.port). |
| mode | 'development' | 'production' | 'test' | 'development' | Build mode. |
| preset | 'spa' | 'ssr' | 'ssg' | 'spa' | High-level pipeline preset. ssr builds dist/browser and dist/node. |
| platform | 'browser' | 'node' | 'edge' | 'browser' | Runtime target. node keeps dependencies external; edge bundles them. |
| plugins | Plugin[] | [] | Lunx plugins; Vite and Rollup plugins work too. |
| lib | { entry, formats, name } | — | Build a library instead of an app (see Library Mode). |
| pwa | boolean | { manifest, register, navigateFallback, exclude } | — | Web app manifest and a service worker that precaches the build (see PWA). |
| electron | false | { main, preload, outDir } | — | Electron entries; found in electron/ by default (see Electron). |
| cacheDir | string | — | Cache root (default .lunx/cache). |
Server
| Field | Type | Default | Description |
|---|---|---|---|
| server.port | number | 5173 | Dev port. |
| server.host | string | — | Bind host, e.g. 0.0.0.0. |
| server.open | boolean | string | false | Open browser on start. |
| server.cors | boolean | { origin } | localhost pages | Which pages may read dev-server responses cross-origin. As Vite since CVE-2025-24010, only pages on localhost by default; true allows any origin. |
| server.allowedHosts | string[] | true | — | Host names answered besides localhost and IPs ('.example.test' for subdomains). Other Host headers get a 403 (DNS rebinding). |
| server.middlewareMode | boolean | false | No port of its own: mount createServer().middlewares in your server, with server.hmr.server for live updates. |
| server.proxy | Record<string, string | object> | — | Dev proxy map, e.g. { '/api': 'http://localhost:8080' }. |
| server.https | boolean | { key, cert } | — | HTTPS for local dev. |
| server.headers | Record<string,string> | — | Extra response headers. |
| server.typecheck | boolean | false | Run the project's tsc (vue-tsc in Vue projects that have it) in watch mode: type errors in the terminal and the overlay's Type Errors tab. |
Build
| Field | Type | Default | Description |
|---|---|---|---|
| build.minify | boolean | — | Minify JS/CSS in production. |
| build.sourcemap | boolean | 'inline' | 'external' | 'hidden' | 'none' | — | Source maps. |
| build.splitting | boolean | — | Code splitting. |
| build.cssModules | boolean | false | CSS modules. |
| build.manualChunks | Record<string, string[]> | — | Manual chunk groups (vendor splitting). |
| build.cache | boolean | true | Skip unchanged builds and reuse compiled components (see Build Cache). |
| build.cssCodeSplit | boolean | true | CSS that only lazy chunks import loads with them; false puts all CSS in one file. |
| build.target | string | string[] | browserslist, else 'baseline-widely-available' | Browsers to compile for: 'es2020', ['chrome90', 'safari14'], 'esnext'. Oxc lowers JS, LightningCSS lowers and prefixes CSS. build.cssTarget sets CSS apart. |
| build.polyfill | 'entry' | 'usage' | 'off' | 'off' | core-js polyfills for the targets: all of them first in each entry, or only those the code uses. |
| build.manifest | boolean | string | — | Write .vite/manifest.json (Vite's format) for Laravel, Rails, Django… backends. build.ssrManifest writes .vite/ssr-manifest.json. |
| build.legalComments | 'linked' | 'inline' | 'none' | 'linked' | Third-party license notices: <chunk>.LICENSE.txt beside each chunk, kept in the code, or dropped. |
| build.assetPrefix | string | — | Load built files from a CDN instead of base. build.renderBuiltUrl(fileName, { hostType }) decides per file. |
| build.entryFileNames / chunkFileNames / assetFileNames | string | 'assets/[name].[hash].js' | Output name templates: [name], [hash], [extname]. |
| build.external | string | RegExp | (string | RegExp)[] | — | Imports left to the page (an import map, a CDN script). |
| build.drop | ('console' | 'debugger')[] | — | Statements removed when minifying. |
| build.prefetch | boolean | false | <link rel="prefetch"> for the lazy chunks each page can load. |
| build.cssMinify / emptyOutDir / copyPublicDir | boolean | true | Minify CSS, empty outDir first, copy public/. |
| build.chunkSizeWarningLimit | number (kB) | 500 | Warn about larger chunks. |
Page (html)
Applied to every page, in dev and builds.
| Field | Type | Default | Description |
|---|---|---|---|
| html.title | string | — | Replaces or adds <title>. |
| html.meta | Record<string, string> | — | <meta name content> tags (replaced when present). |
| html.favicon | string | — | The page icon; a root-relative path gets base. |
| html.preconnect / dnsPrefetch | string[] | — | Origins to connect to early. |
| html.tags | { tag, attrs?, children?, injectTo? }[] | — | Extra tags in head or body (prepend or append). |
| html.cspNonce | string | — | nonce on every script and stylesheet, lunx's own included (Vite's html.cspNonce). |
React
| Field | Type | Default | Description |
|---|---|---|---|
| react.compiler | boolean | object | on when babel-plugin-react-compiler is installed | The React Compiler on components and hooks, in dev and builds; an object passes its options. |
Remote cache
| Field | Type | Default | Description |
|---|---|---|---|
| cache.remote.provider | 'http' | 's3' | — | Share compile results between machines: GET/PUT under baseUrl (token as a bearer token), or S3 / R2 / MinIO with AWS_* credentials from the environment. |
| cache.remote.baseUrl / bucket / region / endpoint | string | — | Where the cache lives. |
| cache.remote.readOnly | boolean | false | Download only (pull requests). |
CSS helpers
| Field | Type | Default | Description |
|---|---|---|---|
| css.framework | 'tailwind' | 'bootstrap' | 'bulma' | 'material' | 'none' | — | Optional CSS framework integration. |
| css.purge | boolean | — | Purge unused CSS when supported. |
| css.critical | boolean | — | Critical CSS extraction. |
Module Federation (MFE)
Short federation block — no webpack config required.
typescriptlunx.config.ts
import { defineConfig } from 'lunx-dev' export default defineConfig({ framework: 'react', federation: { name: 'dashboard', filename: 'remoteEntry.js', remotes: { auth: 'auth@http://localhost:5001/remoteEntry.js', profile: 'profile@http://localhost:5002/remoteEntry.js', }, exposes: { './Button': './src/components/Button.tsx', './StatCard':'./src/components/StatCard.tsx', }, shared: { react: { singleton: true, requiredVersion: '^18.0.0' }, 'react-dom': { singleton: true, requiredVersion: '^18.0.0' }, }, }, })
| Field | Type | Default | Description |
|---|---|---|---|
| federation.name | string | — | Remote/host name. |
| federation.filename | string | — | Remote entry filename (default remoteEntry.js). |
| federation.exposes | Record<string,string> | — | Modules this remote exposes. |
| federation.remotes | Record<string, string | { entry, name?, type? }> | — | Remotes: 'url' (lunx, ES module), 'global@url' (webpack / Rspack script), or an object. |
| federation.shared | string[] | Record<string, { singleton?, requiredVersion?, strictVersion?, eager?, import?: false }> | — | Shared deps, negotiated through a webpack-compatible share scope; import: false takes the package from another app only. |
| federation.shareStrategy | 'loaded-first' | 'version-first' | 'loaded-first' | version-first: every remote joins the scope first, the highest version wins. |
| federation.runtimePlugins | string[] | — | Runtime plugin files (beforeRequest, onLoad, errorLoadRemote), as @module-federation/runtime's. registerRemotes / loadRemote import from '@module-federation/runtime'. |
| federation.dts | boolean | { generateTypes?, consumeTypes? } | true | Types across apps in the @mf-types format (see Module Federation). |
Compared to Vite / webpack
- Shorter: no
rollupOptions/ webpack rules for common SPA + CSS + HMR cases. - Meta-frameworks: SvelteKit, Nuxt, Remix, Astro and others keep their own config and are built by lunx; Next.js runs
next. - Vite configs: a
vite.configis read as is, includingbuild.lib. Next to alunx.config, it still applies underneath (settings and plugins), andlunx.configwins where both set something.
Path alias @/ built-in
Lunx maps
@/ to your src/ directory automatically. Add custom aliases via resolve.alias in the config.