new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Nuxt · Guide · all subjects

builders

19 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

NuxtBuilder interface definition

A builder must implement the NuxtBuilder interface. The only required method is `bundle(nuxt: Nuxt): Promise<void>`. An optional method is `setupWatcher?(nuxt: Nuxt): Promise<void> | void`, which Nuxt calls instead of starting its own file watcher when the user opts in via `experimental.watcher: 'builder'`. The builder should register a `nuxt.hook('close', ...)` to clean up when setupWatcher is implemented.

Builder configuration in nuxt.config.ts

The builder is specified via the `builder` option in nuxt.config.ts. It accepts either a module specifier string that default-exports a NuxtBuilder (such as '@nuxt/vite-builder'), or an inline object implementing the NuxtBuilder interface.

Official builders shipped with Nuxt

Nuxt ships with three official builders: Vite (the default), webpack, and Rspack. These can be selected via the `builder` option in nuxt.config.ts.

Builder responsibilities

A builder is responsible for: bundling the client build (browser bundle) and, when SSR is enabled, the server build (SSR app entry); producing artifacts the server runtime needs to render and hydrate (client manifest, per-component styles map, etc.); and in development, exposing a dev server and triggering reloads when the build changes. The deployable server itself is produced by Nitro via @nuxt/nitro-server, not by the builder.

When builder.bundle is called in Nuxt lifecycle

Nuxt calls `bundle(nuxt)` once during `nuxt build` and `nuxt dev`, after the virtual application has been generated and the `build:before` hook has fired. This occurs in step 4 of the Nuxt build lifecycle. Nuxt wraps the bundle call so that any thrown error automatically triggers the `build:error` hook.

Complete Nuxt build lifecycle

When running `nuxt build` or `nuxt dev`, Nuxt performs these steps in order: 1) Creates the nuxt context and runs modules, populating nuxt.options and build hooks. 2) Generates the virtual application (templates, route table, plugins) into the #build virtual file system. 3) Fires the build:before hook. 4) Resolves the builder and calls builder.bundle(nuxt). 5) Fires the build:done hook, and in production closes the nuxt instance.

Builder branching on nuxt.options.dev

A builder's bundle implementation should branch on nuxt.options.dev. In production, it runs client and server builds to completion, writing artifacts to nuxt.options.buildDir and registering them as build outputs. In development, it sets up a dev server, starts a watching build, assigns nuxt.server, and keeps running.

Module helpers for bundler configuration

Modules influence the bundle through Nuxt Kit helpers that builders should honour: addVitePlugin/addWebpackPlugin register bundler-specific plugins; addBuildPlugin registers an unplugin factory that works across every builder; extendViteConfig/extendWebpackConfig mutate the resolved bundler config.

NuxtBuildOutputs interface keys and types

The NuxtBuildOutputs interface defines the build output contract with these keys: serverEntry (function returning string/Promise<string>): module body re-exporting the SSR app entry; ssrStyles (string or undefined): path to emitted per-component SSR styles map; clientManifest (function returning string/Promise<string>): serialized client manifest for vue-bundle-renderer; clientPrecomputed (function returning string/Promise<string>): serialized precomputed client dependency data; entryChunkName (function returning string/Promise<string>): module body exporting hashed entry chunk filename for import maps; entryIds (function returning string/Promise<string>): module body exporting entry module IDs for inline style extraction.

Build output to nuxt subpath mapping

Build outputs map to nuxt/* subpaths that the server runtime imports: serverEntry → nuxt/entry (SSR app factory); clientManifest → nuxt/manifest (vue-bundle-renderer manifest); clientPrecomputed → nuxt/precomputed (precomputed dependency data); ssrStyles → nuxt/styles (per-component inline-styles map); entryChunkName → nuxt/entry-chunk (hashed entry chunk filename); entryIds → nuxt/entry-ids (entry module IDs for style extraction).

Value providers vs emitted-file paths in build outputs

Build outputs come in two shapes: Value providers (serverEntry, clientManifest, clientPrecomputed, entryChunkName, entryIds) are functions returning module body as a string, which is inlined verbatim into the server bundle and must not depend on file location on disk. Emitted-file path (ssrStyles) is an absolute path to a real module the builder emitted, allowing the runtime to resolve the file's location and relative sibling imports. Leave ssrStyles as undefined when the build produces no inline styles.

setBuildOutput helper usage

Use the setBuildOutput helper from @nuxt/kit to set build outputs. It writes to nuxt.buildOutputs[key]. From inside a bundler plugin with access to the nuxt instance, you can assign nuxt.buildOutputs[key] directly. setBuildOutput is a convenience for code that resolves nuxt via useNuxt(). A provider can be asynchronous and is read lazily when the server build resolves the corresponding nuxt/* import.

Minimal builder example for production

A minimal builder skeleton for a production build: ```ts import { resolve } from 'node:path' import { pathToFileURL } from 'node:url' import { setBuildOutput } from '@nuxt/kit' import type { NuxtBuilder } from '@nuxt/schema' export const bundle: NuxtBuilder['bundle'] = async (nuxt) => { const serverDir = resolve(nuxt.options.buildDir, 'dist/server') // ...run your client and server bundles here, writing artifacts to disk... const { serializedClientManifest } = await runBundles(nuxt, serverDir) if (nuxt.options.ssr) { // Point `nuxt/entry` at the built SSR app entry. const serverEntryURL = pathToFileURL(resolve(serverDir, 'server.mjs')).href setBuildOutput('serverEntry', () => `export { default } from ${JSON.stringify(serverEntryURL)}`) // Provide the client manifest produced by your client build. setBuildOutput('clientManifest', () => `export default ${serializedClientManifest}`) // If you emit a per-component styles map alongside its CSS chunks: setBuildOutput('ssrStyles', resolve(serverDir, 'styles.mjs')) } } ``` This example shows how to set serverEntry, clientManifest, and ssrStyles build outputs for an SSR build.

Development server responsibilities

In development, a builder must populate nuxt.server with the running dev server. The Nuxt CLI consumes it; official builders expose a handler (Node request listener), a fetch (web fetch handler), and reload/close methods. The builder should call nuxt.server.reload() when compilation finishes to signal reloads. Official builders emit hooks like vite:compiled or webpack:compiled that server integration listens to for reloading.

Development build outputs wiring

In development, build outputs are typically wired to live, in-memory sources rather than on-disk files. For example, the SSR entry may be served from the bundler's in-memory output, and the client manifest may be computed from the dev module graph rather than read from nuxt.options.buildDir.

Builder-agnostic contract and Vite Environment API

The build output contract is deliberately builder-agnostic and works for both the legacy path (each builder runs its own bundle, Nitro bundles the deployable separately) and the Vite Environment API path (Nitro runs as a Vite environment). Custom builders only need to satisfy the generic contract. The Vite Environment API integration (experimental.nitroViteEnvironment) is specific to @nuxt/vite-builder; other builders including custom ones use the legacy Nitro Rollup path.

When to author a custom builder

Authoring a builder is an advanced topic. Most apps never need a custom builder. If you only want to influence the bundle, a module that registers bundler plugins is usually the right tool instead of creating a custom builder.

Official builder recognition in Nuxt

Only the three official builder specifiers (@nuxt/vite-builder, @nuxt/webpack-builder, @nuxt/rspack-builder) are recognised by name for builder-specific behaviour elsewhere in Nuxt. A custom builder still works through the generic contract but is treated as the legacy (non-Vite-environment) path.

Default build outputs

The defaults for build outputs are sensible, so you rarely need to provide every key. Default values are: an empty manifest for clientManifest, no inline styles for ssrStyles (leave as undefined), and an undefined entry chunk for entryChunkName. When SSR is disabled, the serverEntry default is a no-op app and most other outputs are unused.

Give your agent this brain