Skip to Content
Docs@utoo/packConfiguration

Configuration

@utoo/pack can be configured with utoopack.json, utoopack.config.mjs, utoopack.config.js, or the Node API.

Configuration Files

utoopack.json
{ "$schema": "@utoo/pack/config_schema.json", "mode": "production", "entry": [ { "import": "./src/index.ts", "html": { "template": "./index.html" } } ], "output": { "path": "./dist", "filename": "[name].[contenthash:8].js", "chunkFilename": "[name].[contenthash:8].js", "clean": true } }

Use utoopack.json when your config is fully JSON-serializable. Use utoopack.config.* when you want type inference or JS-based composition. The config-file form can also carry runtime-only UserConfig fields such as processEnv, watch, dev, buildId, tracing, packPath, projectPath, and rootPath.

Top-level Options

OptionDescription
modeBuild mode: development or production
targetTarget environment
entryEntry points, HTML generation, and library output
outputOutput path, filename templates, public path, asset copying
resolveAliases and extension resolution
defineBuild-time constant replacement
providerAuto-provide modules, similar to Webpack ProvidePlugin
externalsKeep dependencies out of the bundle
moduleCustom module rules and loaders
stylesCSS Modules, Less, Sass, PostCSS, Emotion, styled-components, styled-jsx
imagesAsset inlining behavior
reactJSX runtime and React transform options
mdxRust MDX transform options
reactCompilerRust React Compiler options
optimizationMinification, tree shaking, split chunks, import transforms
devServerHost, port, HTTPS, HMR, proxy
serverServer entries, Server Functions, and server output
sourceMapsEnable source maps
statsEmit build stats
persistentCachingReuse cache across runs
turbopackMemoryEvictionMemory eviction mode for the persistent cache
nodePolyfillPolyfill Node.js built-ins for browser builds
swcPluginsCustom SWC plugins
pluginRuntimeStrategyLoader / plugin process model
experimentalCompatibility entry for reactCompiler and swcPlugins

Core Configuration

mode and target

Build mode affects optimizations and defaults.

{ "mode": "production", "target": "chrome >= 80" }
ValueDescription
developmentFaster builds, better debugging, HMR enabled
productionOptimized output, minification, tree shaking

target is a Browserslist  query. Omit it for a browser build. When the first resolved distribution is node, for example "node 20" or the shorthand "node", the build targets the Node.js platform.

entry

Define application entry points, HTML generation, and library output.

{ "entry": [ { "name": "main", "import": "./src/index.ts", "library": { "name": "MyBundle", "export": ["default"] }, "html": { "template": "./index.html", "filename": "index.html", "title": "My App", "inject": "body", "scriptLoading": "module" } } ] }

output

Configure output path, file naming, static copying, and runtime asset URLs.

{ "output": { "path": "./dist", "type": "standalone", "filename": "[name].[contenthash:8].js", "chunkFilename": "[name].[contenthash:8].js", "cssFilename": "[name].[contenthash:8].css", "cssChunkFilename": "[name].[contenthash:8].css", "assetModuleFilename": "assets/[name].[contenthash:8][ext]", "publicPath": "/", "crossOriginLoading": "anonymous", "copy": ["./public"], "chunkLoadingGlobal": "TURBOPACK", "clean": true, "entryRootExport": "AppExports" } }
OptionDescription
pathOutput directory
typeOutput type: standalone or export
filenameEntry chunk filename template
chunkFilenameNon-entry chunk filename template
cssFilenameMain CSS filename template
cssChunkFilenameCSS chunk filename template
assetModuleFilenameAsset filename template
publicPathPublic URL prefix for assets; also supports runtime and auto
crossOriginLoadingCross-origin attribute for lazy chunks
copyCopy static files into the output directory
chunkLoadingGlobalGlobal variable used by the runtime to load chunks
cleanClean output directory before build
entryRootExportExpose entry exports on window / globalThis

Use publicPath: "runtime" to read the runtime prefix from globalThis.publicPath, or publicPath: "auto" to infer it from the currently loaded script URL.

copy accepts source path strings or { "from": "./public", "to": "static" } objects; to defaults to the source path.

In production, client JS and CSS chunks default to short content-hashed names using Turbopack’s 13-character hash, while development builds keep readable names. Explicit output.filename, output.chunkFilename, and output.cssFilename templates take precedence; use "filename": "[name].js" when consumers need stable entry filenames.

define

Build-time variable replacement.

{ "define": { "process.env.NODE_ENV": "\"production\"", "__VERSION__": "\"1.0.0\"" } }

provider

Automatically inject modules, similar to Webpack ProvidePlugin.

{ "provider": { "$": "jquery", "Buffer": ["buffer", "Buffer"] } }

externals

Exclude dependencies from the bundle.

{ "externals": { "react": "React", "react-dom": "ReactDOM", "lodash-es": { "root": "_", "type": "global" } } }

Externals support simple string globals, script, commonjs, esm, global, and promise forms, plus more advanced subpath configuration.

resolve

Configure module resolution. resolve.alias rewrites an import request to another module or path, using Turbopack-style alias rules .

{ "resolve": { "alias": { "react": "preact/compat", "@/*": "./src/*", "legacy/": "./src/legacy/", "runtime/*": ["./src/runtime/*", "./fallback/runtime/*"] }, "extensions": [".ts", ".tsx", ".js", ".jsx"] } }

resolve.alias accepts this shape:

type ResolveAlias = Record<string, string | string[] | Record<string, string | string[]>>

Matching rules:

AliasMatchesDoes not match
"foo": "./src/foo"import "foo"import "foo/bar"
"foo/*": "./src/foo/*"import "foo/bar" and deeper subpathsimport "foo"
"foo/": "./src/foo/"Same as "foo/*": "./src/foo/*"import "foo"

Use * when you want to carry the matched subpath into the replacement. The * can match across path separators, so "@/*": "./src/*" resolves imports such as @/components/Button.

Alias values can be:

ValueBehavior
stringRewrite to a single package or path
string[]Try multiple candidates in order
condition objectPick a value by condition, commonly browser, with default as the fallback

Relative path values are resolved from the project root, for example "./src/foo". Absolute paths inside the project are normalized to project-relative paths. Avoid aliases that point outside the project directory.

utoopack.config.mjs
import { defineConfig } from '@utoo/pack'; export default defineConfig({ resolve: { alias: { // Exact replacement lodash: 'lodash-es', // Subpath replacement '@/*': './src/*', // Directory shortcut 'components/': './src/components/', // Multiple candidates 'runtime/*': ['./src/runtime/*', './fallback/runtime/*'], // Conditional alias env: { browser: './src/env.browser.ts', default: './src/env.node.ts', }, }, extensions: ['.ts', '.tsx', '.js', '.jsx'], }, });

Migrating from Webpack alias

The biggest difference is subpath matching. In Webpack, an alias such as foo: path.resolve(__dirname, 'src/foo') is commonly used to cover both foo and foo/bar. In Utoopack, a plain key is exact. Add /* or use the trailing slash shortcut when you want subpath imports.

WebpackUtoopack
foo: path.resolve(__dirname, 'src/foo') for import "foo""foo": "./src/foo"
foo: path.resolve(__dirname, 'src/foo') for import "foo/bar""foo/*": "./src/foo/*" or "foo/": "./src/foo/"
'@': path.resolve(__dirname, 'src') for import "@/Button""@/*": "./src/*"
react: 'preact/compat'"react": "preact/compat"

Webpack’s $ suffix marks an exact alias, for example foo$: './src/foo'. Utoopack does not need that suffix because exact matching is the default:

{ "resolve": { "alias": { "foo": "./src/foo" } } }

This only affects:

import "foo"

It does not affect:

import "foo/bar"

To cover subpaths, use:

{ "resolve": { "alias": { "foo/*": "./src/foo/*" } } }

Or the directory shortcut:

{ "resolve": { "alias": { "foo/": "./src/foo/" } } }

module

Define loader-based module rules. Rule objects can include loaders, condition, and type.

{ "module": { "rules": { "*.md": ["raw-loader"], "*.svg": [ { "loaders": [ { "loader": "@svgr/webpack", "options": { "icon": true } } ] } ] } } }

styles

Configure built-in style processing.

{ "styles": { "autoCssModules": true, "cssModules": { "localIdentName": "[local]__[hash:base64:6]" }, "postcss": {}, "less": { "loader": "less-loader", "implementation": "less" }, "sass": { "implementation": "sass" }, "inlineCss": { "injectType": "styleTag" }, "emotion": { "autoLabel": "dev-only" }, "styledComponents": { "displayName": true, "ssr": true }, "styledJsx": { "useLightningcss": true } } }

Use styles.cssModules.localIdentName to customize the CSS Modules class-name template. Use styles.less.loader to select a custom Less loader; implementation selects the Less implementation, and additional fields are forwarded to the loader.

styles.postcss runs after the plugins from a discovered postcss.config.* file in the same PostCSS pass. Set styles.postcss.implementation to an absolute path such as require.resolve("postcss") to pin the PostCSS module used at build time.

images

Configure image inlining.

{ "images": { "inlineLimit": 8192 } }

react

React transform options.

{ "react": { "runtime": "automatic", "importSource": "react", "absoluteSourceFilename": false } }

mdx

mdx enables the Rust MDX transform. It accepts a boolean or an object that configures compilation, the JSX runtime, and the MDX syntax mode.

{ "mdx": { "development": false, "jsx": false, "jsxRuntime": "automatic", "jsxImportSource": "react", "providerImportSource": "@mdx-js/react", "mdxType": "gfm" } }

mdxType supports commonmark and gfm. Use "mdx": true to enable the default configuration.

React Compiler and SWC plugins

reactCompiler accepts a boolean or an object with compilationMode and target for the Rust React Compiler. compilationMode supports infer, annotation, and all; target supports React 17, 18, and 19 and defaults to 19. React 17 and 18 require react-compiler-runtime.

{ "reactCompiler": { "compilationMode": "infer", "target": "19" }, "swcPlugins": [ ["swc-plugin-name", {}] ] }

experimental.reactCompiler and experimental.swcPlugins remain supported. Top-level reactCompiler takes precedence over experimental.reactCompiler; swcPlugins from the top level and experimental are merged.

optimization

{ "optimization": { "minify": true, "extractComments": true, "treeShaking": true, "moduleIds": "deterministic", "splitChunks": { "js": { "minChunkSize": 50000, "maxChunkCountPerGroup": 40, "maxMergeChunkSize": 200000 } }, "cssChunking": "graph", "modularizeImports": { "lodash": { "transform": "lodash/{{member}}", "preventFullImport": true } }, "packageImports": ["package-name"], "transpilePackages": ["shared-ui"], "removeConsole": { "exclude": ["error"] }, "concatenateModules": true, "removeUnusedExports": true, "removeUnusedImports": true } }
OptionTypeDescription
moduleIdsnamed | deterministicModule ID generation strategy
noManglingbooleanPreserve local variable and function names during minification
compressboolean | objectControl compression; object options include passes, sequences, keepClassnames, and keepFnames
minifybooleanMinify output code
extractCommentsbooleanExtract legal comments to [file].LICENSE.txt when minifying library output
treeShakingbooleanRemove unused code
inferModuleSideEffectsbooleanInfer side-effect-free modules from source when package metadata does not declare sideEffects; defaults to true
splitChunksobjectConfigure size and count limits for js / css chunks
cssChunkingboolean | string | objectCSS chunk grouping algorithm
modularizeImportsobjectTransform package imports with templates, similar to babel-plugin-import
packageImportsstring[]Optimize package entry points with many exports
transpilePackagesstring[]Transpile selected dependencies
removeConsoleboolean | objectRemove console calls, with optional methods retained through exclude
concatenateModulesbooleanConcatenate modules to reduce chunk count; the CLI enables it by default in production
removeUnusedExportsbooleanRemove unused exports; defaults off in development and on in production
removeUnusedImportsbooleanRemove unused imports; defaults off in development and on in production
nestedAsyncChunkingbooleanEnable nested async chunks
wasmAsAssetbooleanInline WASM into the bundle; defaults off and emits static assets instead

optimization.packageImports

optimization.packageImports optimizes named imports from packages that export many modules. After adding a package, application code can keep importing from the package root while Utoopack loads only the modules that are actually used, reducing module parsing and compilation overhead in development and production builds. The option accepts a string[] and behaves similarly to Next.js optimizePackageImports.

utoopack.json
{ "optimization": { "packageImports": ["package-name"] } }

Utoopack’s built-in list is maintained with reference to Next.js, but the DEFAULT_OPTIMIZE_PACKAGE_IMPORTS implementation is the source of truth. It currently contains 74 packages or package subpaths:

[ "lucide-react", "date-fns", "lodash-es", "ramda", "react-bootstrap", "ahooks", "@ant-design/icons", "@headlessui/react", "@headlessui-float/react", "@heroicons/react/20/solid", "@heroicons/react/24/solid", "@heroicons/react/24/outline", "@visx/visx", "@tremor/react", "rxjs", "@mui/material", "@mui/icons-material", "recharts", "react-use", "effect", "@effect/schema", "@effect/platform", "@effect/platform-node", "@effect/platform-browser", "@effect/platform-bun", "@effect/sql", "@effect/sql-mssql", "@effect/sql-mysql2", "@effect/sql-pg", "@effect/sql-sqlite-node", "@effect/sql-sqlite-bun", "@effect/sql-sqlite-wasm", "@effect/sql-sqlite-react-native", "@effect/rpc", "@effect/rpc-http", "@effect/typeclass", "@effect/experimental", "@effect/opentelemetry", "@material-ui/core", "@material-ui/icons", "@tabler/icons-react", "mui-core", "react-icons/ai", "react-icons/bi", "react-icons/bs", "react-icons/cg", "react-icons/ci", "react-icons/di", "react-icons/fa", "react-icons/fa6", "react-icons/fc", "react-icons/fi", "react-icons/gi", "react-icons/go", "react-icons/gr", "react-icons/hi", "react-icons/hi2", "react-icons/im", "react-icons/io", "react-icons/io5", "react-icons/lia", "react-icons/lib", "react-icons/lu", "react-icons/md", "react-icons/pi", "react-icons/ri", "react-icons/rx", "react-icons/si", "react-icons/sl", "react-icons/tb", "react-icons/tfi", "react-icons/ti", "react-icons/vsc", "react-icons/wi" ]

Packages configured through optimization.packageImports are merged with this built-in list and de-duplicated.

optimization.cssChunking

optimization.cssChunking supports true, loose, and graph. loose (and true) uses the default grouping algorithm. graph uses graph-based grouping and can be configured with estimated request cost and weight distribution.

utoopack.json
{ "optimization": { "cssChunking": { "type": "graph", "requestCost": 100000, "weightDistribution": 0.1 } } }

false, strict, and { "type": "strict" } are not currently supported by Utoopack and cause the build to fail.

devServer

devServer supports hot, dynamicHmrChunkLists, host, port, https, browserToTerminal, and proxy.

{ "devServer": { "hot": true, "dynamicHmrChunkLists": true, "host": "0.0.0.0", "port": 3000, "https": false, "browserToTerminal": "error", "proxy": [ { "context": ["/api"], "target": "http://localhost:7001", "changeOrigin": true, "pathRewrite": { "^/api": "" } } ] } }

When dynamicHmrChunkLists is enabled, the runtime registers the corresponding HMR chunk lists as dynamic chunks load.

browserToTerminal forwards browser console output to the development terminal: "error" forwards errors, "warn" also forwards warnings, and true forwards all supported console output. It defaults to false.

Each proxy rule supports:

FieldDescription
contextPath prefix or prefixes to match; a value starting with ^ is treated as a regular expression
targetTarget server URL
pathRewriteObject of regex-to-replacement pairs where the first match wins, or a (path) => string function in JS configs
changeOriginRewrite the Host header to match the target; defaults to true
secureVerify the target’s TLS certificate; set false to accept self-signed certificates

server

server configures server entries, Server Functions boundaries, server chunk output, and server-only resolve / externals overrides. entry accepts a single entry string or an array of named entries. The first item in an entry array is the primary server runtime and receives Server Functions.

utoopack.json
{ "server": { "entry": [ { "name": "server", "import": "./src/server.ts" }, { "name": "admin-server", "import": "./src/admin.server.ts" } ], "resolve": { "alias": { "@/*": "./src/*" } }, "externals": { "pg": { "root": "pg", "type": "commonjs" } }, "function": { "clientProxy": "./src/transport.ts", "serverRegister": "./src/register.ts" }, "output": { "path": "./dist/server", "filename": "[name].[contenthash:8].js", "chunkFilename": "chunks/[name].[contenthash:8].js" } } }

For a single entry, use the shorthand "entry": "./src/server.ts". The clientProxy module must export createServerReference(actionId, name), and the serverRegister module must export registerServerReference(action, actionId, name).

server.resolve is applied only to server builds: its alias entries override matching top-level resolve.alias entries, and its extensions replace resolve.extensions when set. server.externals replaces the top-level externals map for server entries and Server Functions when provided; omit it to keep using top-level externals, or set it to {} to disable externals for server builds.

Advanced Options

OptionTypeDescription
sourceMapsbooleanEnable source maps
statsbooleanEnable build statistics output
nodePolyfillbooleanPolyfill Node.js built-ins for browser
persistentCachingbooleanEnable persistent build cache; enabled by default
turbopackMemoryEvictionboolean | auto | fullPersistent-cache memory eviction; defaults to auto; false disables it and true is equivalent to full
swcPlugins[string, any][]Custom SWC plugins and their options
pluginRuntimeStrategyworkerThreads | childProcessesRun loaders / plugins in worker threads or child processes
experimentalobjectCompatibility entry for reactCompiler and swcPlugins

Config-file runtime fields

These UserConfig fields can be used in utoopack.config.* to control the build process.

OptionTypeDescription
processEnvRecord<string, string>Environment variables used during compilation
watchobjectFile-watching options
devbooleanRun in development mode
buildIdstringCurrent build ID
tracingbooleanShow compilation progress; enabled by default. Rust tracing logs are controlled by RUST_LOG
packPathstringAbsolute path to @utoo/pack
projectPathstringProject path
rootPathstringRoot path, which may differ from the project path in a monorepo

watch supports enable, pollIntervalMs, ignored, and nodeModulesRegexes. node_modules is ignored by default. Use !node_modules/<regex> entries in ignored, or package-name regular expressions in nodeModulesRegexes, to include selected dependencies in watching.

utoopack.config.mjs
import { defineConfig } from '@utoo/pack'; export default defineConfig({ entry: [{ import: './src/index.ts' }], watch: { enable: true, pollIntervalMs: 500, ignored: ['node_modules'], nodeModulesRegexes: ['rc-.*', '@rc-component/.*'], }, });

Programmatic API

const { build } = require('@utoo/pack'); await build({ config: { mode: "production", entry: [{ import: "./src/index.ts" }], output: { path: "./dist" } } });

build(options, projectPath?, rootPath?) and serve(options, projectPath?, rootPath?, serverOptions?) accept either BundleOptions, which is the config object plus runtime fields such as processEnv, watch, dev, buildId, tracing, and packPath, or a WebpackConfig in compatibility mode. When rootPath is omitted it is discovered from the project path. serverOptions for serve() supports port, hostname, https, logServerInfo, selfSignedCertificate, and an onReady callback that fires once the first build is written and the server is listening.

For the full configuration schema, see config_schema.json .

Last updated on