📦 obuild 😯
✅ Zero-config ESM/TS package builder powered by rolldown.
Used by
Usage
CLI
npx obuild ./src/index.ts
npx obuild ./src/runtime/:./dist/runtime
You can use --dir to set the working directory.
If paths end with /, obuild uses transpile mode using oxc-transform instead of bundle mode with rolldown.
Programmatic
import { build } from "obuild";
await build({
cwd: ".",
entries: ["./src/index.ts"],
});
Config
You can use build.config.mjs (or .ts) or pass config to build() function.
import { defineBuildConfig } from "obuild/config";
export default defineBuildConfig({
entries: [
{
type: "bundle",
input: ["./src/index.ts", "./src/cli.ts"],
},
{
type: "transform",
input: "./src/runtime",
outDir: "./dist/runtime",
},
],
hooks: {
},
});
Stub Mode
When working on a package locally, it can be tedious to rebuild or run the watch command every time.
You can use stub: true (per entry config) or the --stub CLI flag. In this mode, obuild skips the actual build and instead links the expected dist paths to the source files.
- For bundle entries,
.mjs and .d.mts files re-export the source file.
- For transpile entries, src dir is symlinked to dist.
Caveats:
- You need a runtime that natively supports TypeScript. Deno, Bun, Vite, and Node.js (1)
- For transpile mode, you need to configure your bundler to resolve either
.ts or .mjs extensions.
- For bundle mode, if you add a new entry or add/remove a
default export, you need to run the stub build again.
(1) For Node.js, you have several options:
- Using
node --experimental-strip-types (Available in 22.6)
- Using jiti (
node --import jiti/register)
- Using oxc-node (
node --import @oxc-node/core/register)
- Using unloader (
node --import unloader/register)
Prior Arts
- unbuild: Stable solution based on rollup and mkdist.
- tsdown: Alternative bundler based on rolldown.
License
💛 Released under the MIT license.