lunx.docs
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

FieldTypeDefaultDescription
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.
entrystring | string[]—App entry. Default often src/main.tsx.
outDirstring'dist'Production output folder.
portnumber5173Dev 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.
pluginsPlugin[][]Lunx plugins; Vite and Rollup plugins work too.
lib{ entry, formats, name }—Build a library instead of an app (see Library Mode).
pwaboolean | { manifest, register, navigateFallback, exclude }—Web app manifest and a service worker that precaches the build (see PWA).
electronfalse | { main, preload, outDir }—Electron entries; found in electron/ by default (see Electron).
cacheDirstring—Cache root (default .lunx/cache).

Server

FieldTypeDefaultDescription
server.portnumber5173Dev port.
server.hoststring—Bind host, e.g. 0.0.0.0.
server.openboolean | stringfalseOpen browser on start.
server.corsboolean | { origin }localhost pagesWhich 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.allowedHostsstring[] | true—Host names answered besides localhost and IPs ('.example.test' for subdomains). Other Host headers get a 403 (DNS rebinding).
server.middlewareModebooleanfalseNo port of its own: mount createServer().middlewares in your server, with server.hmr.server for live updates.
server.proxyRecord<string, string | object>—Dev proxy map, e.g. { '/api': 'http://localhost:8080' }.
server.httpsboolean | { key, cert }—HTTPS for local dev.
server.headersRecord<string,string>—Extra response headers.
server.typecheckbooleanfalseRun 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

FieldTypeDefaultDescription
build.minifyboolean—Minify JS/CSS in production.
build.sourcemapboolean | 'inline' | 'external' | 'hidden' | 'none'—Source maps.
build.splittingboolean—Code splitting.
build.cssModulesbooleanfalseCSS modules.
build.manualChunksRecord<string, string[]>—Manual chunk groups (vendor splitting).
build.cachebooleantrueSkip unchanged builds and reuse compiled components (see Build Cache).
build.cssCodeSplitbooleantrueCSS that only lazy chunks import loads with them; false puts all CSS in one file.
build.targetstring | 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.manifestboolean | 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.assetPrefixstring—Load built files from a CDN instead of base. build.renderBuiltUrl(fileName, { hostType }) decides per file.
build.entryFileNames / chunkFileNames / assetFileNamesstring'assets/[name].[hash].js'Output name templates: [name], [hash], [extname].
build.externalstring | RegExp | (string | RegExp)[]—Imports left to the page (an import map, a CDN script).
build.drop('console' | 'debugger')[]—Statements removed when minifying.
build.prefetchbooleanfalse<link rel="prefetch"> for the lazy chunks each page can load.
build.cssMinify / emptyOutDir / copyPublicDirbooleantrueMinify CSS, empty outDir first, copy public/.
build.chunkSizeWarningLimitnumber (kB)500Warn about larger chunks.

Page (html)

Applied to every page, in dev and builds.

FieldTypeDefaultDescription
html.titlestring—Replaces or adds <title>.
html.metaRecord<string, string>—<meta name content> tags (replaced when present).
html.faviconstring—The page icon; a root-relative path gets base.
html.preconnect / dnsPrefetchstring[]—Origins to connect to early.
html.tags{ tag, attrs?, children?, injectTo? }[]—Extra tags in head or body (prepend or append).
html.cspNoncestring—nonce on every script and stylesheet, lunx's own included (Vite's html.cspNonce).

React

FieldTypeDefaultDescription
react.compilerboolean | objecton when babel-plugin-react-compiler is installedThe React Compiler on components and hooks, in dev and builds; an object passes its options.

Remote cache

FieldTypeDefaultDescription
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 / endpointstring—Where the cache lives.
cache.remote.readOnlybooleanfalseDownload only (pull requests).

CSS helpers

FieldTypeDefaultDescription
css.framework'tailwind' | 'bootstrap' | 'bulma' | 'material' | 'none'—Optional CSS framework integration.
css.purgeboolean—Purge unused CSS when supported.
css.criticalboolean—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' },
    },
  },
})
FieldTypeDefaultDescription
federation.namestring—Remote/host name.
federation.filenamestring—Remote entry filename (default remoteEntry.js).
federation.exposesRecord<string,string>—Modules this remote exposes.
federation.remotesRecord<string, string | { entry, name?, type? }>—Remotes: 'url' (lunx, ES module), 'global@url' (webpack / Rspack script), or an object.
federation.sharedstring[] | 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.runtimePluginsstring[]—Runtime plugin files (beforeRequest, onLoad, errorLoadRemote), as @module-federation/runtime's. registerRemotes / loadRemote import from '@module-federation/runtime'.
federation.dtsboolean | { generateTypes?, consumeTypes? }trueTypes 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.config is read as is, including build.lib. Next to a lunx.config, it still applies underneath (settings and plugins), and lunx.config wins where both set something.
Path alias @/ built-in
Lunx maps @/ to your src/ directory automatically. Add custom aliases via resolve.alias in the config.