Monopack CLI
Monopack CLI is a JavaScript bundler designed for Node.js monorepo applications, aiming to create static, deterministic deliverables. It bundles all imported monorepo sources into a single `main.js` file, alongside a pruned `package.json`, `yarn.lock`, and `node_modules` containing only the truly used third-party dependencies. Originally conceived to streamline continuous integration and deployment for serverless functions, micro-services, and monolithic servers within a monorepo structure, its last known stable release is 0.2.6, published in September 2018. Due to its age and lack of recent updates, the project appears to be abandoned, and its compatibility with modern Node.js and Yarn versions is uncertain.
Common errors
-
Error: Cannot find module 'some-dynamically-required-module'
cause Monopack's static analysis may not detect modules that are dynamically required at runtime (e.g., certain database drivers or plugins).fixUse the `--with-extra-module <module-name>` CLI option to explicitly include such dependencies. For example: `monopack build main.js -m mysql`. -
command not found: monopack
cause The `monopack` command is not accessible in your system's PATH. This typically happens if it's not installed globally, or if installed locally, it's not being invoked correctly.fixIf installed globally, ensure your global npm/yarn bin directory is in your PATH. If installed locally, invoke it via `yarn run monopack <command>` (if configured in `package.json` scripts) or `./node_modules/.bin/monopack <command>`.
Warnings
- breaking Monopack CLI appears to be an abandoned project, with its last release (v0.2.6) in September 2018. It is highly unlikely to be compatible with modern Node.js versions (e.g., Node.js 16+ or newer) or Yarn 2+.
- gotcha Deterministic dependency collection is only guaranteed if your project uses Yarn (>= 1.3.2). While Monopack can work with npm, the resulting dependency tree might not be as predictable.
- gotcha When adding extra modules via `--with-extra-module`, ensure that the package is installed in the same monorepo package as your main entrypoint. If it's installed elsewhere, Monopack might pick up an unintended version or fail to resolve it.
Install
-
npm install monopack-cli -
yarn add monopack-cli -
pnpm add monopack-cli
Imports
- monopack (global installation)
require('monopack')monopack <command>
- monopack (local installation via Yarn)
monopack <command>
yarn run monopack <command>
- monopack (local installation via npm)
monopack <command>
./node_modules/.bin/monopack <command>
Quickstart
import { execSync } from 'child_process';
import * as fs from 'fs';
import * as path from 'path';
import * as os from 'os';
// Create a temporary directory for the mock monorepo
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'monopack-demo-'));
const appPackageDir = path.join(tempDir, 'packages', 'my-app');
const sharedLibDir = path.join(tempDir, 'packages', 'shared-lib');
console.log(`Setting up mock monorepo in: ${tempDir}`);
// Create application package structure
fs.mkdirSync(path.join(appPackageDir, 'src'), { recursive: true });
fs.writeFileSync(path.join(appPackageDir, 'package.json'), JSON.stringify({
name: 'my-app',
version: '1.0.0',
main: 'src/main.js',
dependencies: {
'lodash': '^4.17.21' // Third-party dependency
}
}, null, 2));
fs.writeFileSync(path.join(appPackageDir, 'src', 'main.js'), `
const _ = require('lodash');
const { getMessage } = require('shared-lib'); // Monorepo dependency
console.log(_.toUpper(getMessage('Monopack Demo')));
`);
// Create shared library package structure
fs.mkdirSync(sharedLibDir, { recursive: true });
fs.writeFileSync(path.join(sharedLibDir, 'package.json'), JSON.stringify({
name: 'shared-lib',
version: '1.0.0',
main: 'index.js'
}, null, 2));
fs.writeFileSync(path.join(sharedLibDir, 'index.js'), `
exports.getMessage = (topic) => 'Hello from shared-lib, ' + topic + '!';
`);
// Simulate monorepo setup with yarn and install local monopack
try {
console.log('\nInstalling dependencies and linking shared-lib...');
execSync(`cd ${appPackageDir} && yarn add file:${sharedLibDir}`, { stdio: 'inherit' });
execSync(`cd ${appPackageDir} && yarn install`, { stdio: 'inherit' });
execSync(`cd ${appPackageDir} && yarn add -D monopack-cli@0.2.6`, { stdio: 'inherit' });
console.log('\n--- Running monopack build ---');
const outputDir = path.join(appPackageDir, 'dist');
// Execute monopack locally using its path in node_modules
execSync(`cd ${appPackageDir} && ./node_modules/.bin/monopack build src/main.js --out-dir ${outputDir}`, { stdio: 'inherit' });
console.log(`\nBuild successful. Output directory contents for 'my-app': ${outputDir}`);
console.log(fs.readdirSync(outputDir));
console.log('\n--- Running the bundled application ---');
// To run the bundled application, it usually requires its own node_modules
// which monopack should have generated in the output directory.
execSync(`cd ${outputDir} && node main.js`, { stdio: 'inherit' });
} catch (error: any) {
console.error('\nAn error occurred during the quickstart execution:', error.message);
if (error.stdout) console.error('stdout:', error.stdout.toString());
if (error.stderr) console.error('stderr:', error.stderr.toString());
} finally {
console.log(`\nCleaning up temporary directory: ${tempDir}`);
fs.rmSync(tempDir, { recursive: true, force: true });
}