Keep AGENTS.md updated with project status.
- CLI:
src/cli.ts- Usesnode:utilparseArgsandc12for config loading (build.config.{ts,js,...}) - Programmatic API:
src/index.ts- Exportsbuild()and types - Config helper:
src/config.ts- ExportsdefineBuildConfig()
- Resolve
cwd, readpackage.json - Normalize entries (string shorthand or typed objects)
- Fire
hooks.start,hooks.entries - Clean output directories
- For each entry: run bundle or transform builder
- Fire
hooks.end, print summary
- Uses rolldown for bundling
- Uses rolldown-plugin-dts for
.d.mtsgeneration (enabled by default,dts: falseto disable) - Output: ESM (
.mjs) with code-splitting fornode_modulesinto_chunks/libs/ - Externals: Node.js builtins +
dependencies+peerDependenciesfrompackage.json - Plugins: shebang (executable detection), license (third-party license file)
- Stub mode: generates re-export files pointing to source
- Post-build: reports size, minified size, gzip size, side-effect size per entry
- Uses oxc-transform (via
rolldown/utils) for file-by-file.ts->.mjstranspilation - Uses magic-string + exsolve for import specifier rewriting (
.ts->.mjs) - Supports isolated declarations via oxc (
stripInternal: true) - Supports
filteranddtscallback functions per entry - Non-
.tsfiles are copied as-is (or symlinked in stub mode) - Parallel file processing with
Promise.allSettled
- shebang.ts - Detects
#!lines and makes output files executable (chmod 0o755) - license.ts - Generates
THIRD-PARTY-LICENSES.mdfrom bundled dependencies (based on Vite's approach)
BuildConfig- Top-level config:cwd,entries,hooksBuildEntry=BundleEntry | TransformEntryBundleEntry-type: "bundle",input(string/array),minify,rolldownoptions,dtsTransformEntry-type: "transform",input(directory),minify,oxcoptions,resolve,filter,dtsBuildHooks-start,end,entries,rolldownConfig,rolldownOutput
fmtPath()- Format path relative to cwdanalyzeDir()- Count files and total byte sizedistSize()- Bundle and measure: raw, minified, min+gzip sizessideEffectSize()- Measure side-effect code size via tree-shaking
obuild [entries...] [--dir <path>] [--stub]Entry string shorthand:
src/indexorsrc/index,src/cli-> bundle entry (comma-separated for multiple inputs)src/runtime/-> transform entry (trailing slash)src/index:dist/custom-> custom output directory (after:)
build.config.ts (loaded via c12):
import type { BuildConfig } from "obuild/config";
export default { entries: [...] } satisfies BuildConfig;| Dependency | Purpose |
|---|---|
rolldown |
Bundler (Rust-based, Rollup-compatible) |
rolldown-plugin-dts |
Declaration file generation for bundle |
rolldown/utils |
transformSync, parseSync, minifySync (oxc) |
exsolve |
Module path resolution |
magic-string |
Source text manipulation for import rewriting |
c12 |
Config file loading |
consola |
Logging |
tinyglobby |
Fast glob for transform directory scanning |
defu |
Deep defaults merging |
pathe |
Cross-platform path utilities |
pretty-bytes |
Human-readable file sizes |
# Enable node via fnm
eval "$(fnm env --use-on-cd 2>/dev/null)"
# Run tests
pnpm vitest run test/obuild.test.ts
# Build
pnpm build
# Lint
pnpm lint
# Type check
pnpm test:types # uses tsgotest/obuild.test.ts- Integration test: builds fixture, verifies output files, validates exports, checks shebang permissionstest/fixture/- Test fixture withbuild.config.ts, bundle entries (index,cli,utils), and transform entry (runtime/)