A zero‑config (yet configurable) CLI to scaffold, develop, build, and publish modern JavaScript / TypeScript / React libraries.
Create a production‑ready npm package in seconds: pick a template, start a hot‑reloading dev server, bundle to ESM + CJS (and optionally a single bundle), generate type declarations, and publish – all with one tool.
- Rapid project creation with four templates:
- TypeScript library
- JavaScript library
- React + TypeScript component library
- React + JavaScript component library
- Development server with hot reload + optional Express middleware (
express.ts/express.js) - Automatic dependency graph tracking (via
madge) for efficient reloads - Incremental TypeScript compilation and declaration output
- Dual module build (
esm,cjs, or both) with optional single bundled file - Tree‑shaken and optionally minified output
- Sourcemaps & type declarations by default
- Clean build output in an isolated
.mpackdirectory (publish‑ready) - Simple release workflow (
makepack releaseornpm run releaseguidance)
Install globally (recommended) or use npx.
npm install -g makepack # global
# or
npx makepack create # without global installCreate a new project:
makepack create
# Answer the interactive prompts:
# - Project name
# - TemplateEnter the project (if created in a new folder) and start the dev server:
cd your-project
npm startBuild the library:
makepack buildRelease (after building):
makepack release # publishes the contents of ./.mpack to npmTip: You can also run via package scripts (auto‑generated or added manually):
npm run build/npm run start.
Depending on template, you’ll get something like:
your-lib/
package.json
readme.md
tsconfig.json (TypeScript templates)
src/
index.(ts|js|tsx|jsx)
(React templates include an example component + export)
During development/build:
.mpack/ # Build output (cleaned & regenerated each build)
package.json # Stripped (scripts & "type" removed for publishing clarity)
readme.md
dist files # ESM/CJS outputs + declarations + sourcemaps
Do not edit files inside
.mpackdirectly. Treat it as a disposable publish directory.
Run: makepack start --port 3000
Features:
- Hot reload on dependency change
- Optional custom Express bootstrap via a root
express.tsorexpress.jsexporting a default function(app) => { ... } - Safe handler wrapping to catch async errors
Example express.ts:
import { Express } from 'express';
export default function routes(app: Express) {
app.get('/health', (_req, res) => {
res.json({ ok: true, ts: Date.now() });
});
}If present, it’s reloaded automatically when edited.
Command:
makepack build [options]| Option | Default | Values | Description |
|---|---|---|---|
--format / -f |
both |
cjs, esm, both |
Module formats to output |
--bundle / -b |
false |
true/false |
Bundle into a single file (rollup/esbuild assisted) |
--minify / -m |
false |
true/false |
Minify output (Terser) |
--sourcemap / -s |
true |
true/false |
Emit source maps |
--declaration / -d |
true |
true/false |
Emit TypeScript .d.ts files |
Behavior notes:
- The tool auto‑detects
src/index.(ts|js|tsx|jsx)as the entry. - Boolean flags accept either actual booleans or string equivalents:
--minify=true. - Output is always placed in
.mpack/(cleaned each run). package.jsonin output hasscriptsandtyperemoved for neutral publishing.
Dual build with declarations (default):
makepack buildESM only, minified, bundled:
makepack build --format=esm --bundle=true --minify=trueDisable sourcemaps & declarations (faster):
makepack build -s=false -d=false- Ensure you are logged in to npm:
npm login - Build your package:
makepack build - Publish from the generated directory:
- Quick command:
makepack release - Manual:
cd .mpack && npm publish
- Quick command:
The release command simply runs
npm publishinside.mpackafter verifying a build exists.
Add express.ts or express.js in the project root. Export a default function receiving the Express app. Example with middleware:
import compression from 'compression';
export default function(app) {
app.use(compression());
app.get('/', (_req, res) => res.send('Hello from makepack dev server'));
}The file and all its dependency graph (resolved via madge) are watched; edits trigger a reload.
| Area | Tooling |
|---|---|
| CLI | commander |
| Dev Server | express, vite, chokidar, madge |
| Builds | rollup, @rollup/plugin-*, esbuild, rollup-plugin-dts, terser |
| UX | inquirer, ora |
| FS/Utils | fs-extra, lodash.debounce |
| Template | Use Case | Entry | Extras |
|---|---|---|---|
typescript |
Library in TypeScript | src/index.ts |
tsconfig.json |
javascript |
Plain JS library | src/index.js |
– |
react with typescript |
React component library (TSX) | src/index.tsx |
React + types setup |
react with javascript |
React component library (JSX) | src/index.jsx |
React setup |
Generated React templates export a sample component you can replace.
create→ scaffold + install depsstart→ hot dev (optionally with express middleware)build→ produce distributable code in.mpackrelease→ publish the build to npm
makepack create # Interactive project scaffolding
makepack start --port 4000 # Start dev server on custom port
makepack build [flags] # Build library
makepack release # Publish from .mpackSee build flags in the Build System section.
You can wire scripts (some templates already do this):
Run with npm run build etc.
- Keep a clean root: limit extra build artifacts outside
src/. - Export your public API from a single
src/index.*. - Use semantic versioning (e.g.
npm version patch). - For React libraries, avoid bundling peer deps – list
react&react-domaspeerDependenciesin your ownpackage.jsonbefore publishing. - Add a LICENSE file (see below) – required for many consumers.
| Issue | Cause | Fix |
|---|---|---|
| "No entry file found" | Missing src/index.* |
Create src/index.ts or equivalent |
| Express not reloading | File outside dependency graph | Import files directly from `express.(ts |
| Declarations missing | --declaration=false or JS template |
Use TS template or enable flag |
| Publish fails | Not built | Run makepack build first |
| ESM import errors | Missing "type": "module" in root |
Add type back in your source project (it’s stripped only in .mpack) |
Contributions welcome! Suggested flow:
- Fork & clone
- Create a feature branch:
git checkout -b feat/your-idea - Implement + add/update docs
- Commit with conventional style:
feat(build): add xyz - Open a PR
Please include clear reproduction steps for any bug fix.
- Plugin system for custom build steps
- Peer dependency auto‑detection
- Template customization presets
- E2E test harness
No network calls are performed beyond npm install/publish and user code execution. Always audit generated dependencies before publishing.
Report vulnerabilities via GitHub Issues (consider labeling as security). Avoid posting exploit details publicly – request a private channel if needed.
License: TBD (e.g. MIT). Add a LICENSE file such as:
MIT License
Copyright (c) 2025 Devnax
Permission is hereby granted, free of charge, to any person obtaining a copy...
Why strip scripts and type from the published package.json?
To minimize accidental exposure of internal scripts and to keep the distributed package neutral; consumers rarely need them.
Can I output only one format?
Yes: --format=esm or --format=cjs.
How do I include assets (e.g. CSS)?
Import them from your entry; configure rollup/esbuild plugins in future versions (PRs welcome) – currently you’d manually copy in a post-step.
Does it support monorepos?
Not natively; you can still run it per package folder.
Why another tool?
To reduce the ceremony of picking + wiring rollup, tsconfig, scripts, vite dev preview, express hooks, and publish layout – all unified.
Open an issue for bugs, ideas, or questions: https://github.com/devnax/makepack/issues
{ "scripts": { "start": "makepack start --port 3000", "build": "makepack build", "release": "makepack release" } }