Tiny build helper for monorepo packages
makage is a tiny, cross-platform build helper that replaces common build tools like cpy and rimraf with zero dependencies. It provides essential commands for managing package builds in monorepos.
makage =
make+package. A delightful portmanteau, like brunch for build tools—except makage actually gets things done.
- One-command builds -
makage buildruns clean, TypeScript compilation, and asset copying - Development mode - Add
--devfor source maps and faster iteration - Glob pattern support - Copy files using patterns like
src/**/*.sql(replacement forcopyfiles) - Cross-platform copy - Copy files with
--flatand--footeroptions (replacement forcpy) - Cross-platform clean - Recursively remove directories (replacement for
rimraf) - README + Footer concatenation - Combine README with footer content before publishing
- Assets helper - One-command copying of LICENSE, README, and package.json
- Build TypeScript helper - Run both CJS and ESM TypeScript builds
- Update workspace dependencies - Automatically convert internal package references to
workspace:* - Zero dependencies - Uses only Node.js built-in modules
npm install makageReplace your existing build scripts with makage:
{
"scripts": {
"build": "makage build",
"build:dev": "makage build --dev",
"prepublishOnly": "npm run build"
}
}See how makage simplifies your build scripts:
Before:
"build:dev": "npm run clean; tsc -p tsconfig.json --declarationMap; tsc -p tsconfig.esm.json --declarationMap; npm run copy"After:
"build:dev": "makage build --dev"Or if you need more control:
"build:dev": "makage clean && makage build-ts --dev && makage copy"Before:
"copy": "copyfiles -f ../../LICENSE README.md package.json dist"After:
"copy": "makage copy ../../LICENSE README.md package.json dist --flat"Bonus: Add --footer to automatically concatenate your README with a footer:
"copy": "makage copy ../../LICENSE README.md package.json dist --flat --footer"Before:
"copy:sql": "copyfiles -f src/migrate/sql/* dist/migrate/sql && copyfiles -f src/migrate/sql/* dist/esm/migrate/sql"After:
"copy:sql": "makage copy src/migrate/sql/* dist/migrate/sql --flat && makage copy src/migrate/sql/* dist/esm/migrate/sql --flat"Or with recursive patterns:
"copy:all-sql": "makage copy src/**/*.sql dist/sql --flat"Note: For convenience,
makage assetscombines copy + footer functionality and is kept for backwards compatibility.
# Full build (clean + build-ts + assets)
makage build
# Full build with development mode (adds --declarationMap)
makage build --dev
# Clean build directories (defaults to "dist")
makage clean
makage clean dist build temp # or specify multiple directories
# Build TypeScript (both CJS and ESM)
makage build-ts
# Build TypeScript with source maps for development
makage build-ts --dev
# Copy files to destination
makage copy ../../LICENSE README.md package.json dist --flat
# Copy files with glob patterns
makage copy src/migrate/sql/* dist/migrate/sql --flat
makage copy src/**/*.sql dist/sql --flat
# Copy with automatic README + footer concatenation
makage copy ../../LICENSE README.md package.json dist --flat --footer
# Copy standard assets (LICENSE, package.json, README+FOOTER)
makage assets
# Concatenate README with footer (lower-level command)
makage readme-footer --source README.md --footer FOOTER.md --dest dist/README.md
# Update workspace dependencies
makage update-workspace
# Detect outdated cross-repo dependencies (structured JSON output)
makage update-deps --from ./constructive --in .The update-deps command enables deterministic, version-aware dependency synchronization across repositories. It is the engine behind the constructive-hub update-constructive-deps workflow.
- Discovers all packages in a source pnpm workspace (by reading
pnpm-workspace.yaml) - Scans the target repo's
package.jsonfiles (supports both monorepo and non-workspace layouts) - Cross-references dependencies to find packages that exist in both source and target
- Compares versions using semver to identify outdated packages
- Outputs structured JSON to stdout for CI consumption (logs go to stderr)
makage update-deps --from <source-workspace> --in <target-repo>| Flag | Description |
|---|---|
--from |
Path to the source pnpm workspace (contains pnpm-workspace.yaml) |
--in |
Path to the target repo to scan for outdated deps |
{
"sourcePackages": [{ "name": "@constructive/foo", "version": "1.2.3", "path": "packages/foo" }],
"matchedPackages": [{ "name": "@constructive/foo", "currentVersion": "^1.1.0", "availableVersion": "1.2.3", "depType": "dependencies", "consumer": "@myapp/bar", "outdated": true }],
"outdatedPackages": [/* subset of matchedPackages where outdated=true */],
"has_dep_changes": true
}The update-deps command is used in GitHub Actions to automatically update downstream repos when the source workspace publishes new versions. The typical CI flow:
- Check out the target repo + source workspace side by side
- Run
makage update-deps --from ./constructive --in .for structured JSON detection - Parse the JSON output to extract outdated package names
- Run
pnpm update -r --latest <packages...>to update them - Create a PR with the results
Target repos are categorized into two strategies:
- Workspace repos (have
pnpm-workspace.yaml): Usepnpm update -r --latestfor bulk updates - Non-workspace repos (e.g., template repos): Update each
package.jsonindividually viajqor per-directorypnpm update
The constructive-hub workflow currently updates:
constructive-db(default, also triggers schema propagation)dashboardpgpm-modulesdev-utilssandbox-templatespgpm-boilerplates
For detailed usage and API documentation, see packages/makage/README.md.
- Clone the repository:
git clone https://github.com/constructive-io/makage.git- Install dependencies:
cd makage
pnpm install
pnpm build- Test the package:
cd packages/makage
pnpm test:watchBuilt for developers, with developers.
👉 https://constructive.io
AS DESCRIBED IN THE LICENSES, THE SOFTWARE IS PROVIDED "AS IS", AT YOUR OWN RISK, AND WITHOUT WARRANTIES OF ANY KIND.
No developer or entity involved in creating this software will be liable for any claims or damages whatsoever associated with your use, inability to use, or your interaction with other users of the code, including any direct, indirect, incidental, special, exemplary, punitive or consequential damages, or loss of profits, cryptocurrencies, tokens, or anything else of value.