hoist-all
v0.1.1
Published
Copy all non-existing node_modules from apps/* into root node_modules in a monorepo.
Maintainers
Readme
TL;DR
This package fixes errors caused by modules not being found because they exist only in an app’s local node_modules.
It hoists (or reverses) them into the right place and now supports scoping, so you can easily switch between sets of dependencies (e.g. mobile, web) without reinstalling everything.
hoist-all
hoist-all is an NPM package for managing dependencies in monorepos. It supports two main features:
- Hoisting – copy/symlink modules from app-level
node_modulesinto the rootnode_modules. - Scoped installs – isolate sets of
node_modulesinto named scopes (mobile,web, etc.) and switch between them instantly.
Installation
Install it in the root package.json:
npm install hoist-all --save-devUsage
1. Postinstall Hoisting (classic mode)
Add it to the root package.json:
"scripts": {
"postinstall": "hoist-all"
}After you run:
npm i -w your_apphoist-all will automatically symlink or copy dependencies into the root node_modules.
2. Scoped Workspaces (new)
You can now save and switch between scopes. This is useful if you have many apps/packages but only want certain ones active at a time.
Save a scope
hoist-all s mobile "app1|app2" "shared|ui"mobile→ the scope name"app1|app2"→ regex for apps to include"shared|ui"→ regex for packages to include
This saves the current node_modules into .hoist-all/mobile/ and remembers your regex filters.
Install a scope
hoist-all i mobile- Restores
node_modulesfrom.hoist-all/mobile/ - Applies your app/package filters
- Switches
active_scopein.hoist-all/state.json
Example
my-workspace/
apps/
app1/
app2/
app3/
packages/
shared/
utils/
node_modules/
# Save only app1 + shared into "mobile" scope
hoist-all s mobile "app1" "shared"
# Switch to mobile
hoist-all i mobileCLI Reference
hoist-all [appsFolder] [workspaceRoot]appsFolder(optional) – Defaults toappsworkspaceRoot(optional) – Defaults tocwd
Scope Commands
hoist-all s <scopeName> [appsRegex] [packagesRegex]-a, --apps <path>– Folder containing apps (default:apps)-p, --packages <path>– Folder containing packages (default:packages)
hoist-all i <scopeName>Install a previously saved scope.
hoist-all lsList available scopes and show the active one.
Features
Hoist mode: Copy/symlink modules from app-level
node_modules→ root.Reverse-hoist mode: If
hoist.target = "app", copy from root → app.Scoped dependency management:
- Save root + app/package
node_modulesinto.hoist-all/<scope> - Restore instantly without reinstall
- Save root + app/package
Regex-based filtering for apps/packages
Skips system folders silently
Reports copied/restored modules
Zero runtime dependencies
Configuration
App-level config
Each app can define where dependencies should live:
{
"name": "my-app",
"hoist": {
"target": "root" // or "app"
}
}Default is "root".
Scope config (auto-managed)
Stored in .hoist-all/state.json:
{
"active_scope": "mobile",
"appsFolder": "apps",
"packagesFolder": "packages",
"scopes": {
"mobile": {
"appsRegex": "app1|app2",
"packagesRegex": "shared|ui"
}
}
}Example
Workspace
my-workspace/
node_modules/
apps/
app1/
node_modules/
lodash/
app2/
node_modules/
axios/Classic hoist
npx hoist-allResult: lodash and axios appear in the root node_modules.
Scoped workflow
# Save a scope
hoist-all s web "app2" "ui"
# Switch scopes
hoist-all i mobile
hoist-all i webLicense
MIT
