lpm bundle
Bundle the project with Rolldown through an LPM CLI-managed plugin.
lpm bundle [--entry <path>] [--out-dir <dir>] [--config <file>] [-- args...]Runs Rolldown through an LPM CLI-owned command surface. Common bundle flags are exposed directly, and anything after -- is forwarded to Rolldown unchanged.
--entry maps to Rolldown's --input, and --out-dir maps to Rolldown's --dir. If you omit both, Rolldown falls back to its config file or upstream defaults.
Examples
lpm bundle --entry src/index.js --out-dir dist
lpm bundle --config rolldown.config.mjs
lpm bundle --entry src/index.js --format esm --platform browser --minify --sourcemap
lpm bundle -- --watch
lpm bundle --all --config rolldown.config.mjs
lpm bundle --filter web --entry src/index.js --out-dir dist
lpm bundle --affected --base develop --config rolldown.config.mjsManaged Rolldown plugin
lpm bundle does not rely on a project-local rolldown dependency. On first use, LPM CLI installs its approved Rolldown version into ~/.lpm/engines/rolldown/<version>/<platform>/, verifies every tarball's SRI integrity, preserves the full extracted package layout, and reuses that verified cache on later runs.
Rolldown's managed layout is a composed npm package tree: the root rolldown package, @rolldown/pluginutils, @oxc-project/types, and the platform-specific native binding.
~/.lpm/engines/
└── rolldown/
└── 1.0.2/
└── darwin-arm64/
├── bin/cli.mjs
├── node_modules/@rolldown/pluginutils/
├── node_modules/@oxc-project/types/
├── node_modules/@rolldown/binding-darwin-arm64/
└── .lpm-engine.jsonThe engine sidecar records the engine identity, platform, entry path, every package's install subdir and tarball metadata, per-package SHA-256s, and a hash of the extracted layout. Reuse re-hashes the installed layout before Rolldown runs, so a tampered tree or mismatched package definition becomes a cache miss instead of trusted state.
Rolldown is managed through the public plugin command family:
lpm plugin outdated
lpm plugin update rolldownlpm bundle itself never checks the network for the upstream latest version. It uses the bundled verified floor or a newer version already approved by lpm plugin update rolldown.
Pinning Rolldown
Pin Rolldown per project in lpm.json:
{
"tools": {
"rolldown": "1.1.3"
}
}The pin is exact. The version must be either the bundled verified floor or a version already approved in the sticky cache by lpm plugin update rolldown; otherwise lpm bundle exits before launching Node and tells you to run the update command.
Node runtime
LPM CLI manages Rolldown, not Node itself. lpm bundle still needs node available through the normal PATH chain. The usual path is:
lpm use node@22That installs a managed Node runtime and makes it available to LPM CLI commands. A system node on PATH also works.
Forwarding Rolldown flags
Anything after -- is passed straight to Rolldown:
lpm bundle --entry src/index.js --out-dir dist -- --watch
lpm bundle --config rolldown.config.mjs -- --external react --treeshakeThis is the escape hatch for upstream flags LPM CLI does not surface directly.
Workspaces
lpm bundle --all # every member
lpm bundle --filter web # exact name
lpm bundle --filter '@scope/*' # glob
lpm bundle --filter './apps/*' # path glob
lpm bundle --filter-prod ...shared # prod graph closure
lpm bundle --affected # members changed vs main
lpm bundle --affected --base develop # change base branch
lpm bundle --filter web --fail-if-no-match # exit non-zero on typo'd filterMembers run in topological levels, with packages inside each level executing in parallel up to the available CPU count. The managed Rolldown plugin is resolved once before workspace fan-out, so a cold install happens once per workspace run, not once per member.
--all and --affected are mutually exclusive; filters compose with --affected (the affected set is unioned with the filter result). --filter-prod uses the same grammar as --filter, but closure operators ignore devDependencies.
Filter grammar is documented in Workspaces.
Watch mode
lpm bundle -- --watch works in single-package mode.
In workspace mode, watch is only supported when the selection resolves to exactly one member. If --all, --affected, or a broad filter resolves to multiple members, LPM CLI exits with an error instead of starting one watcher per package.
Flags
| Flag | Effect |
|---|---|
--entry <PATH> | Entry file to bundle |
--out-dir <DIR> | Output directory for bundle artifacts |
--config <PATH> | Explicit Rolldown config file |
--format <esm|cjs|iife> | Output format |
--platform <node|browser|neutral> | Target platform |
--minify | Minify the bundle output |
--sourcemap | Emit a sourcemap |
--all | Run in every workspace member |
--filter <expr> | Select workspace members by the filter grammar (repeatable; entries union) |
--filter-prod <expr> | Select workspace members with production-only dependency closures |
--affected | Run only in members affected by changes vs --base |
--base <REF> | Git base ref for --affected (default: main) |
--changed-files-ignore-pattern <glob> | Ignore matching git-diff paths for --affected / [git-ref] filters |
--test-pattern <glob> | Treat matching git-diff paths as test-only for --affected / [git-ref] fan-out decisions |
--fail-if-no-match | Exit non-zero if no member matches the filter set (recommended in CI) |
Anything after -- (or trailing) is forwarded to Rolldown.
Plus the global flags.
--json in workspace mode
Single-package mode preserves Rolldown's stdout — LPM CLI does not wrap it. Workspace mode emits one LPM CLI envelope on stdout, with per-member stdout/stderr captured only on failure:
{
"success": false,
"packages": 3,
"succeeded": 2,
"failed": 1,
"duration_ms": 1840,
"members": [
{ "name": "web", "success": true, "exit_code": 0, "duration_ms": 420 },
{
"name": "api",
"success": false,
"exit_code": 1,
"duration_ms": 180,
"stdout": "...",
"stderr": "..."
}
]
}Spawn/config/engine failures surface as exit_code: null paired with an error string, distinguishing “ran and exited non-zero” from “could not even launch.”
See also
lpm check— type-checking, with project-localtscor managedtsgolpm lint— Oxlint- Built-in tools — managed plugins, project-local tools, and internal engines