npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@b9g/libuild

v0.1.20

Published

Zero-config library builds

Downloads

601

Readme

libuild

Zero-config library builds with ESBuild.

Libuild is a build tool for JavaScript/TypeScript libraries which publish to NPM. It solves ESM/CJS support, type generation, and produces clean packages with just the files and configuration needed by consumers.

Installation

npm install -D @b9g/libuild
bun add -d @b9g/libuild

Usage

# Build your library (development mode - no package.json changes)
libuild build

# Build and update package.json for npm link
libuild build --save

# Build and publish to npm
libuild publish

Features

  • No configuration - Source files and standard package.json are all you need
  • Multiple formats - Supports ESM, CJS, UMD, and generates d.ts files
  • Clean output - Only necessary files and fields go into the package
  • Development-friendly - NPM link just works and changes can be saved to package.json

Convention = Configuration

Entry Points

  • Library modules: All top-level .js/.ts files in src/ (excluding _ prefixed files)
  • CLI binaries: Any file referenced in package.json bin field gets compiled to standalone executable
  • UMD builds: If src/umd.ts exists, creates browser-compatible UMD build

Output Structure

  • Structure-preserving: src/index.tsdist/src/index.js (maintains src/ directory)
  • ESM: .js files with ES module syntax
  • CommonJS: .cjs files for Node.js compatibility
  • TypeScript: .d.ts declaration files (when TypeScript is available)
  • Clean package.json: Optimized for consumers (no dev scripts)

Format Control

  • ESM-only: Remove the main field from package.json to skip CommonJS builds
  • CommonJS detection: Presence of main field enables .cjs builds
  • UMD builds: Add src/umd.ts for browser-compatible builds

Export Aliases

  • Legacy support: ./entry.js automatically aliases to ./entry
  • Package.json: Always exported as ./package.json
  • Custom exports: Existing exports in package.json are preserved and enhanced

Package.json Transformations

  • Development mode (default): Root package.json unchanged, no git noise
  • --save mode: Root package.json updated to point to ./dist/src/* artifacts for npm link
  • Dist package.json: Clean consumer-ready version with relative src/ paths
  • Bin paths: Automatically transformed from src/ references to built artifacts
  • Exports field: Generated for all entry points with proper types-first ordering

Examples

Simple Library

Given this structure:

src/
  index.ts
  utils.ts
  _internal.ts  # ignored (underscore prefix)

Produces:

dist/
  src/
    index.js       # ESM
    index.cjs      # CommonJS
    index.d.ts     # TypeScript declarations
    utils.js
    utils.cjs
    utils.d.ts
  package.json     # Clean consumer version

Library with CLI

package.json:
{
  "bin": { "mytool": "src/cli.js" }
}

src/
  index.ts
  cli.ts

Produces:

dist/
  src/
    index.js
    index.cjs
    index.d.ts
    cli.js         # Compiled CLI
    cli.cjs
    cli.d.ts
  package.json     # bin: { "mytool": "./src/cli.js" }

ESM-Only Library

To build only ESM (no CommonJS), remove the main field:

// package.json
{
  "name": "my-lib",
  "module": "dist/src/index.js",  // ESM entry
  "types": "dist/src/index.d.ts"
  // no "main" field = no CJS
}

Produces:

dist/
  src/
    index.js       # ESM only
    index.d.ts
    utils.js       # ESM only
    utils.d.ts
  package.json     # ESM-only exports

Multi-Format with UMD

src/
  index.ts
  utils.ts
  umd.ts         # Browser build entry

Produces:

dist/
  src/
    index.js
    index.cjs
    index.d.ts
    utils.js
    utils.cjs
    utils.d.ts
    umd.js         # UMD browser build
  package.json

Generated Package.json Exports

Dual format (ESM + CommonJS):

{
  "main": "src/index.cjs",
  "module": "src/index.js",
  "types": "src/index.d.ts",
  "exports": {
    ".": {
      "types": "./src/index.d.ts",
      "import": "./src/index.js",
      "require": "./src/index.cjs"
    },
    "./utils": {
      "types": "./src/utils.d.ts",
      "import": "./src/utils.js",
      "require": "./src/utils.cjs"
    },
    "./utils.js": {
      "types": "./src/utils.d.ts",
      "import": "./src/utils.js",
      "require": "./src/utils.cjs"
    },
    "./package.json": "./package.json"
  }
}

ESM-only (no main field in source):

{
  "module": "src/index.js",
  "types": "src/index.d.ts",
  "type": "module",
  "exports": {
    ".": {
      "types": "./src/index.d.ts",
      "import": "./src/index.js"
    },
    "./utils": {
      "types": "./src/utils.d.ts",
      "import": "./src/utils.js"
    },
    "./utils.js": {
      "types": "./src/utils.d.ts",
      "import": "./src/utils.js"
    },
    "./package.json": "./package.json"
  }
}

Root package.json (with --save):

{
  "main": "./dist/src/index.cjs",
  "module": "./dist/src/index.js",
  "types": "./dist/src/index.d.ts",
  "exports": {
    ".": {
      "types": "./dist/src/index.d.ts",
      "import": "./dist/src/index.js",
      "require": "./dist/src/index.cjs"
    }
  }
}

Commands

libuild build (default)

Builds your library in development mode:

  • Compiles all entry points to multiple formats
  • Generates TypeScript declarations
  • Creates optimized package.json files
  • Preserves root package.json (no git noise)

libuild build --save

Builds and updates root package.json for npm link:

  • Everything from libuild build
  • Updates root package.json to point to dist artifacts
  • Perfect for testing with npm link

libuild publish

Builds and publishes to npm:

  • Runs full build with --save
  • Warns if root package.json is not private
  • Publishes from dist directory with clean package.json

Requirements

  • Node.js 16+ or Bun 1.0+ (for running libuild)
  • TypeScript (optional, for .d.ts generation)
  • No runtime requirements for library consumers

License

MIT