SkillAgentSearch skills...

Bunchee

Zero config bundler for npm packages

Install / Use

/learn @huozhi/Bunchee
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

bunchee

Zero-config bundler for JS/TS packages.

bunchee

<p align="left"> <a href="https://npm.im/bunchee"> <img src="https://badgen.net/npm/v/bunchee"> </a> <a href="https://github.com/huozhi/bunchee/actions?workflow=CI"> <img src="https://github.com/huozhi/bunchee/workflows/CI/badge.svg"> </a> </p>

bunchee is a zero-configuration bundler designed to streamline package building by adhering to the exports field in your package.json. Powered by Rollup and SWC ⚡️, it generates output based on your config, supporting both CommonJS and ESModules.

By using the standard exports configuration as the single source of truth, bunchee automatically aligns entry file conventions with your exports, ensuring seamless and efficient builds.

Quick Start

Installation

npm install --save-dev bunchee typescript

Configuration

Create entry files of your library and package.json.

cd ./coffee
mkdir src && touch ./src/index.ts && touch package.json

Add the exports in package.json.

{
  "name": "coffee",
  "type": "module",
  "main": "./dist/index.js",
  "scripts": {
    "build": "bunchee"
  }
}

Build

npm run build

Usage

Entry Files

Then files in src folders will be treated as entry files and match the export names in package.json. Simply like Node.js module resolution, each export name will match the file in src/ directory.

Here's a example of entry files and exports configuration:

| File | Exports Name | | -------------------- | ---------------------- | | src/index.ts | "." (default export) | | src/lite.ts | "./lite" | | src/react/index.ts | "./react" |

{
  "name": "coffee",
  "scripts": {
    "build: "bunchee",
  },
  "type": "module",
  "exports": {
    // entry: ./src/index.ts
    ".": {
      "import": "./dist/index.js",
      "require": "./dist/index.cjs",
    },

    // entry: ./src/lite.ts
    "./lite": "./dist/lite.js",

    // entry: ./src/react/index.ts
    "./react": "./dist/react.js",
  },
}

Wildcard Exports

bunchee supports wildcard patterns in the exports field to automatically generate exports for multiple files:

{
  "exports": {
    ".": "./dist/index.js",
    "./features/*": "./dist/features/*.js"
  }
}

This will automatically discover files in src/features/ and generate exports like ./features/foo, ./features/bar, etc. The wildcard * is substituted in both the export path and output path.

Output Formats

bunchee detects the format of each entry-point based on export condition type or the file extension. It supports the following output formats:

| package.json Field | Output format | | -------------------- | -------------------------------- | | main | Default | | types | TypeScript declaration | | exports | Default | | exports.require | CommonJS | | exports.import | Default | | exports.types | TypeScript declaration of export | | bin | Default | | bin.<name> | Default |

The Default output format is determined by the file extension:

| File Extension | Output format | | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | .js | Determined by package.json#type, CommonJS by default | | .cjs | CommonJS | | .mjs | ECMAScript Modules |

External Dependencies

The dependencies and peerDependencies will be marked as externalized and wont be included in the bundle. If you want to include them in the bundle, you can use the --no-external option. Or you can import the devDependencies in your source code to bundle them.

{
  // Externalized
  "dependencies": {
    /* ... */
  },
  "peerDependencies": {
    /* ... */
  },

  // Bundled
  "devDependencies": {
    /* ... */
  },
}

Multiple Runtime

For exports condition like react-native, react-server and edge-light as they're special platforms, they could have different exports or different code conditions. In this case bunchee provides an override input source file convention if you want to build them as different code bundle.

For instance:

{
  "exports": {
    "react-server": "./dist/react-server.mjs",
    "edge-light": "./dist/edge-light.mjs",
    "import": "./dist/index.mjs",
  },
}

Path Alias

bunchee supports both TypeScript paths config and Node.js imports field in package.json for path aliasing. It will resolve the path alias to the correct file path. If you're using modern TypeScript versions, you can also directly configure the imports field in package.json and it will work as a charm.

// package.json
{
  "imports": {
    "#util": "./src/utils.ts",
  },
}

Binary CLI

To build executable files with the bin field in package.json, bunchee requires you to create the bin directory under src directory. The source file matching will be same as the entry files convention.

For example:

|- src/
  |- bin/
    |- index.ts

This will match the bin field in package.json as:

{
  "bin": "./dist/bin.js",
}

If you have multiple binaries, you can create multiple files under the bin directory. Check the below example for more details.

<details> <summary>Multiple Binaries</summary>

For named executable files, you can create multiple files under the bin directory.

|- src/
  |- bin/

This will match the bin field in package.json as:

{
  "bin": {
    "foo": "./dist/bin/a.js",
    "bar": "./dist/bin/b.js",
  },
}
</details>

Note: For multiple bin files, the filename should match the key name in the bin field.

Native Addon (.node) Support

bunchee supports bundling native Node.js addon files (.node binaries). When you import a .node file, it will be copied to the output directory and the import will be rewritten to load it at runtime.

// src/index.js
import addon from './native-addon.node'

Server Components

bunchee supports building React Server Components and Server Actions with directives like "use client" or "use server". It generates separate chunks for the server or client boundaries. When integrated to framework like Next.js, it can correctly handles the boundaries with the split chunks.

Shared Modules

Sometimes, you may want to share a chunk across multiple bundles without promoting it to separate entries or exports, such as single instance of React context module, shared utils, etc. In these cases, shared modules will help you achieve the goal. Files or directories prefixed with an underscore (_<name>.<ext> or _<name>/**) will be treated as shared modules.

These conventions are kept private and are not going to be treat as shared modules or entry points. For example, test or mock files like _foo/a.test.ts will be ignored and not included as shared modules.

<details> <summary>Shared Utils Example</summary>
// src/_util.js
export function sharedUtil() {
  /* ... */
}

You can then use them in different entry files:

// src/index.js
import { sharedUtil } from './_util'
// src/lite.js
import { sharedUtil } from './_util'

bunchee will bundle the shared module into a separate chunk, keeping it private and ensuring it's referenced by multiple entry bundles.

</details>

For scenarios involving multiple runtime bundles, such as default and react-server, modules that need to be shared and remain as a single instance across different runtime bundles can also follow this convention. The leading underscore (_) ensures that these modules are private to your application while facilitating reuse.

<details> <summary>Shared Runtime Module Example</summary>
'use client'
// src/_app-context.js
export const AppContext = React.createContext(null)

These modules can be imported in various runtime entry files:

// src/index.js
import { AppContext } from './_app-context'
// src/index.react-server.js
import { AppContext } from './_app-context'

The _app-context module will be bundled into a shared chunk that exists as a single instance across different runtime bundles.

</details>

This convention keeps shared modules private while enabling efficient bundling and reuse across your codebase.

CLI

Options

bunchee CLI provides few options to create different bundles or generating types. Call bunchee --help to see the help information in the terminal.

Here are the available options for the CLI:

cd <project-root-dir>

# Build based on the package.json configuration
bunchee --runtime node -o ./dist/bundle.js
bunchee -f esm -o --target es2022 ./dist/bundle.esm.js

# Specify the input source file
bunc

Related Skills

View on GitHub
GitHub Stars1.4k
CategoryDevelopment
Updated2d ago
Forks36

Languages

TypeScript

Security Score

85/100

Audited on Mar 22, 2026

No findings