--- url: https://toolchain.deltabox.studio/guide/vite.md --- # Vite+ The `vite` section holds the **entire Vite+ configuration**. Every key is passed through verbatim to Vite+, so `dbx.config.*` stays the only hand-authored root config; `dbx sync` writes a thin root `vite.config.ts` that resolves it at load time. ```ts [dbx.config.ts] export default defineConfig({ toolchain: { vite: { fmt: { semi: true, singleQuote: true }, lint: { ignorePatterns: ['dist/**'] }, test: { include: ['src/**/*.test.ts'], environment: 'node' }, run: { tasks: { build: { command: 'tsdown --config-loader unrun' } } }, }, }, }); ``` The section is typed as Vite+'s own config (`ToolchainViteConfig` = Vite's `UserConfig` as augmented by Vite+), so the whole Vite+ surface autocompletes in `dbx.config.ts`. ## The generated shim `dbx sync` writes a fixed `vite.config.ts`: ```ts [vite.config.ts] import { defineConfig, type ViteUserConfig } from 'vite-plus'; // Generated by @deltabox/toolchain — edit the vite section in dbx.config and run `dbx sync`. import { resolveVite } from '@deltabox/toolchain/vite'; export default defineConfig(resolveVite({ cwd: import.meta.dirname })); ``` The shim imports `defineConfig` from whichever Vite package the project installs — `vite` or `vite-plus` (detected from `package.json`, walking up so a hoisted workspace dependency is found). For a plain `vite` project it imports `defineConfig, type UserConfig` from `vite` and calls `resolveVite`, so the same shim type-checks against both. `resolveVite(options?)` resolves the **same-directory** `dbx.config.*` (so a nested workspace `vite.config.ts` uses its own config), or the `toolchain` you pass, then returns `toolchain.vite`. You can also pass inline overrides with `resolveVite({ vite: { ... } })`, which are deep-merged over the loaded section. The file never drifts, because the real config stays in `dbx.config.*`. The root shim must live at the **root**: `vp run`, `vp check` and `vp staged` do not accept `--config`, so the shim has to be the file Vite+ loads. ## Options | Option | Type | Default | Description | | -------- | ------------------- | ------- | ----------------------------------------------- | | `config` | `boolean \| string` | `true` | Write the managed shim; a string sets its path. | Everything else under `vite` is Vite+ config (plugins, `test`, `lint`, `fmt`, `run.tasks`, ...). `vite.fmt` / `vite.lint` override `toolchain.fmt.oxc` / `toolchain.lint.oxc` (deep merge). `fmt: true` / `lint: true` use the shared `DEFAULT_FMT_RULES` / `DEFAULT_LINT_RULES`; an options object is merged over them. Their ignore lists are exported as `DEFAULT_FMT_IGNORE_PATTERNS` / `DEFAULT_LINT_IGNORE_PATTERNS` (both layered over `DEFAULT_IGNORE_PATTERNS`) from `@deltabox/toolchain` and `@deltabox/toolchain/shared`, so you can extend them instead of repeating the defaults. Import sorting is part of those defaults: `sortImports` gets a `workspace` custom group resolved from every dbx project (see `resolveFmtCustomGroups`), so workspace packages do not need manual groups. Set `vite: { config: false }` to leave a hand-written `vite.config.ts` alone (the section is still read for provider colouring and the `dbx` provider passthrough). `config: 'config/vite.custom.ts'` writes the shim there instead (relative to the project, or an absolute path inside it). ## Keep the shim out of Oxfmt Add the shim to `vite.fmt.ignorePatterns`, otherwise `vp fmt` rewrites the generated file and `dbx sync --check` reports drift: ```ts vite: { fmt: { ignorePatterns: ['/vite.config.ts']; } } ``` In a monorepo, put `**/vite.config.ts` on the **root** config so every workspace shim is covered (workspace `fmt` settings are inherited, but an `ignorePatterns` array in a workspace replaces the root's list). `dbx migrate --from vite` adds the ignore for you (see [Migrations](/guide/migrations/#vite-config)). When `fmt` / `lint` are defined, `dbx sync` also writes `.oxfmtrc.json` / `.oxlintrc.json` for the Oxc VS Code extension. They are root-only unless a workspace config defines its own `fmt` / `lint`. ## Commands Vite+ commands are reachable directly or through the `vite` namespace, and are registered as a provider (see [Providers](/guide/providers)): ```sh dbx fmt # the active formatter (vp fmt when Oxc) dbx run -r build # forwards to `vp run -r build` dbx vite dev # explicit namespace (always works) dbx vite:build # named alias for `vp build` ``` A bare `dbx ` is forwarded to Vite+ when the name (or a Vite+ alias) matches — built-in commands win, so `dbx migrate` stays the toolchain's migration. `dbx fmt` / `dbx lint` route to the configured/discovered Biome/Prettier/Dprint/ESLint tool, and keep the `vp` passthrough when the active tool is Oxc (see [Formatting & linting](/guide/formatting#running-the-active-tool)). ## Programmatic API ```ts import { resolveVite, renderViteConfig, viteConfigObject, viteProvider, viteSyncTask, } from '@deltabox/toolchain/vite'; ``` | Export | Description | | ------------------------------ | --------------------------------------------------------------------------------- | | `resolveVite(options?)` | Resolve `toolchain.vite` (or a passed `toolchain`), with inline `vite` overrides. | | `detectViteSpecifier(cwd)` | Which package (`vite` / `vite-plus`) the project has, for the shim import. | | `renderViteConfig(specifier?)` | The managed `vite.config.ts` shim source (defaults to `vite-plus`). | | `viteConfigObject(config?)` | The `vite` section without the toolchain opt-out `config`. | | `viteSyncTask()` | The sync task (writes the shim). | | `viteProvider()` | The Vite+ provider descriptor. | See [Configuration](/guide/config/vite) for the `dbx.config` integration and the [Providers](/guide/providers) guide for the passthrough commands.