pkgroll: Zero-config JavaScript package bundler

repository·master·Indexed Apr 15, 2026

https://github.com/privatenumber/pkgroll

pkgroll is a zero-config JavaScript package bundler powered by Rollup and esbuild. It automatically builds packages from entry-points defined in package.json, supporting TypeScript, ESM, CommonJS, and .d.ts outputs. Features include automatic dependency externalization, wildcard exports, subpath imports, alias configuration via import maps or tsconfig paths, build target customization, ESM/CJS interoperability, native module handling, import attributes, environment variable injection, minification, watch mode, and source map generation.

Tokens
6.9K
Snippets
30
Records
60
Agent score
76%

What's inside pkgroll

  1. Install pkgroll

    master

    Install pkgroll as a development dependency in your project:

    npm install --save-dev pkgroll

    Once installed, you can run it directly via npx pkgroll or add it to your package.json scripts.

    npm install --save-dev pkgroll

    Sources: README.md

  2. Handle native Node.js addons (.node files)

    master

    pkgroll automatically handles native Node.js addons (.node files) by copying them to the output directory and generating the correct require paths. When you import a .node file, the bundler:

    1. Copies the file to a natives subdirectory within your dist folder.
    2. Generates a virtual module that re-exports the file using a relative require path.
    3. Handles filename collisions by appending a counter (e.g., module_1.node).

    No configuration is required. Simply import your native modules as you normally would in your source code, and pkgroll will ensure they are bundled correctly alongside your JavaScript.

    // Example: Importing a native module in your source code
    import nativeAddon from './path/to/native-addon.node';
    
    // pkgroll will copy native-addon.node to dist/natives/native-addon.node
    // and generate: export default require("./natives/native-addon.node");

    Sources: src/rollup/plugins/native-modules.ts

  3. Configure externalizeDependencies plugin options

    master

    The externalizeDependencies plugin accepts optional configuration:

    {
      skipUnlistedWarnings?: boolean; // Skip warnings for unlisted dependencies
      forTypes?: boolean;             // Enable @types package warnings
    }
    • skipUnlistedWarnings: Useful for type declaration builds where imports may not match runtime dependencies. Prevents warnings when bundling unlisted packages.
    • forTypes: Enables specific warnings about @types package mismatches. Only relevant when building type definitions.

    These options are typically set internally by pkgroll based on the build context.

    Sources: src/rollup/plugins/externalize-dependencies.ts

  4. privatenumber/pkgroll

    master
    pkgroll is a zero-config JavaScript package bundler powered by Rollup that automatically builds packages from entry-points defined in package.json. It supports TypeScript, ESM, CommonJS, and .d.ts outputs out of the box, using esbuild for transformation and minification.
  5. Define build-time constants

    master

    Use the --define flag to replace specific strings in your code at build time. This is useful for dead code elimination and conditional compilation.

    pkgroll --define.process.env.NODE_ENV='"production"' --define.DEBUG=false

    Note: Unlike --env, values are not automatically JSON stringified, so you need to include quotes for string values.

    pkgroll --define.process.env.NODE_ENV='"production"' --define.DEBUG=false

    Sources: README.md

  6. Understand dependency externalization rules

    master

    pkgroll automatically externalizes dependencies based on their classification in package.json:

    • dependencies, peerDependencies, optionalDependencies: Always externalized. These are treated as runtime dependencies and are not bundled.
    • devDependencies: Bundled by default if resolvable. If a devDependency is not resolvable, the build fails with an error.
    • Unlisted dependencies: Bundled with a warning to prevent runtime failures.

    This behavior ensures that your published package only includes code necessary for its runtime, while relying on the consumer's environment for declared dependencies.

    Sources: src/rollup/plugins/externalize-dependencies.ts

  7. Troubleshoot package.json parsing errors

    master

    If pkgroll fails to read your project configuration, it may throw a parsing error. The tool attempts to load package.json or package.yaml from the project directory. If the file exists but contains invalid JSON or YAML syntax, pkgroll will throw an error with the message: Failed to parse <path>: <error message>. Ensure your package.json or package.yaml is valid and properly formatted.

    Sources: src/utils/read-package.ts

  8. Dependencies with native modules

    master

    If using packages with native modules (e.g., chokidar which depends on fsevents):

    • In dependencies/peerDependencies: Works automatically (externalized).
    • In devDependencies: Bundled. If they use bindings() or node-pre-gyp, move them to dependencies to avoid build errors.

    Example:

    {
        "dependencies": {
            "chokidar": "^3.0.0"
        }
    }

    Note: Native modules are platform and architecture-specific. Ensure you distribute the correct .node files for your target platforms.

    {
        "dependencies": {
            "chokidar": "^3.0.0"
        }
    }

    Sources: README.md

  9. Wildcard exports

    master

    You can use wildcard patterns in exports to bundle multiple modules automatically. Patterns must include a file extension (e.g., .mjs, .cjs).

    Example:

    {
        "exports": {
            "./utils/*": "./dist/utils/*.mjs",
            "./components/*/index": "./dist/components/*/index.mjs"
        }
    }

    This maps:

    • src/utils/format.tsdist/utils/format.mjs
    • src/components/button/index.tsdist/components/button/index.mjs
  10. Manage dependency bundling and externalization

    master

    pkgroll automatically externalizes dependencies based on their type in package.json:

    • Externalized: peerDependencies, dependencies, optionalDependencies
    • Bundled: devDependencies

    When generating type declarations (.d.ts), type dependencies in devDependencies are also bundled and tree-shaken.

    Example:

    {
        "peerDependencies": {
            "react": "^18.0.0"
        },
        "dependencies": {
            "lodash": "^4.17.21"
        },
        "devDependencies": {
            "typescript": "^5.0.0"
        }
    }

    In this case, react and lodash are externalized, while typescript is bundled.

    {
        "dependencies": {
            "lodash": "^4.17.21"
        }
    }

    Sources: README.md