NPM build tool that prepares packages for distribution. Supports two modes: copy (file copy with version replacement) and bundle (esbuild multi-format builds).
"copy"(default): Copiessrc/todist/, replaces{version}in the main file. Used by large projects that don't need bundling (e.g., UJM)."bundle": Uses esbuild to produce ESM (index.mjs), CJS (index.js), and/or IIFE (minified, for CDN<script>tags). Used by client-side libraries (e.g., chatsy).
src/
index.js # Main entry: resolves config, branches copy vs bundle, safety checks, CDN purge
build.js # Esbuild config generator, version plugin, build() and createWatchContexts()
watch.js # Watch mode: chokidar for copy, esbuild contexts for bundle
cli.js # Interactive CLI for project setup (npx pp / npx prepare-package)
logger.js # Timestamped console logger with chalk colors
dist/ # Copy-mode output of src/ (prepare-package builds itself with copy mode)
Interactive setup wizard that configures a project's package.json:
- Asks copy or bundle mode
- Asks source/output directories (defaults:
src/dist) - If bundle: asks formats, auto-derives
globalName(TitleCase of package name) andfileName({name}.min.js) - Writes
preparePackageconfig andprepare/prepare:watchscripts topackage.json
preparescript: Runs onnpm installandnpm publishin the consumer's projectpostinstallscript: Runs when prepare-package itself is installed as a dependency. Skips bundle mode (esbuild may not be available yet during install)prepare:watchscript: Starts watch mode (chokidar for copy, esbuild.watch()for bundle)bincommands:prepare-packageandppboth point tocli.js
All config lives in preparePackage key in the consumer's package.json:
- Blocks publish if any local
file:dependencies are found - Removes sensitive files (
.env,.DS_Store, etc.) from the package - Purges jsDelivr CDN cache after publish
- esbuild is a direct dependency but only
require()'d inside bundle code paths (lazy-loaded) - Bundle mode's version plugin replaces
{version}in all.jsfiles at build time - IIFE build auto-unwraps default export:
GlobalName=GlobalName.default||GlobalName.GlobalName||GlobalName; - Copy mode's
{version}replacement only applies to the main file - prepare-package builds itself using copy mode (it's both the tool and a consumer of itself)
- Self-hosting: prepare-package uses itself (copy mode) to build
src/→dist/ - No breaking changes to copy mode — existing consumers must keep working unchanged
- Bundle mode is opt-in via
type: "bundle"
{ "preparePackage": { "input": "src", // Source directory "output": "dist", // Output directory "type": "copy", // "copy" (default) or "bundle" "build": { // Only used when type: "bundle" "entry": "src/index.js", "formats": ["esm", "cjs", "iife"], "target": "es2020", "platform": "neutral", "external": [], "sourcemap": false, "iife": { "globalName": "MyLib", // Required for IIFE "fileName": "my-lib.min.js" // Default: "{name}.min.js" } } } }