A fast Node.js package manager that drops into existing projects.
aube means dawn in French. Pronounced /ob/, like "ohb".
Why Try It
Fast installs. Warm installs are about 8x faster than pnpm and about 7x faster than Bun in the current benchmarks. Repeat test commands run up to 32x faster than pnpm and up to 6x faster than Bun.
Existing lockfiles. Reads and writes pnpm-lock.yaml, package-lock.json, npm-shrinkwrap.json, yarn.lock, and bun.lock in place.
Cheap repeat commands. aubr test, aube test, and aube exec vitest auto-install when dependencies are stale, then skip that work when nothing changed. aubx uses a local binary when one is installed, or a throwaway environment for one-off tools.
Less disk use. A global content-addressable store lets projects share package files instead of keeping a full copy of the same dependencies in every checkout.
Secure defaults. Out of the box, exotic transitive deps are blocked, lifecycle scripts wait for approval, trust downgrades fail at resolve, and brand-new releases sit in a 24h cooling window. One paranoid: true line adds the build jail and turns the soft gates into hard fails.
Install
The recommended path is mise:
mise can also manage the Node.js versions
your projects need. If your projects already pin Node through package.json
(devEngines.runtime), .nvmrc, or .node-version, enable mise's
idiomatic version-file support for Node:
mise settings add idiomatic_version_file_enable_tools node
Check that it is on your PATH:
Inside a project, you can also pin aube with mise:
aube is also published on npm:
npm install -g --ignore-scripts=false @endevco/aube npx --ignore-scripts=false @endevco/aube --version
The npm package uses an install script to fetch native binaries for performance. The npm commands above include the flag that keeps that working even if your npm config disables scripts. We still recommend mise for the smoothest install and runtime management path.
Homebrew installs come from the Endev tap:
brew install endevco/tap/aube
First Run
Run aube in an existing Node.js project:
aubr is shorthand for aube run. Before it starts the script, aube checks
whether node_modules is fresh for the current package.json and lockfile.
If dependencies are missing or stale, it installs them first; otherwise it
goes straight to the script.
You usually do not need a separate aube install in day-to-day work. Run the
script or binary you actually wanted:
aubr build aube test aube exec vitest aubx cowsay hi
Use aube install when the install itself is the task: first local setup
without running a script, updating a lockfile, Docker layers, production-only
installs, or CI flows.
If the project already has a supported lockfile, aube reads it and writes updates back to the same file. That makes it easy to try aube locally without forcing the rest of the team to switch package managers first.
For a new project with no lockfile, aube creates aube-lock.yaml.
Daily Commands
aube add react # add a dependency aube add -D vitest # add a dev dependency aube remove react # remove a dependency aube update # update dependencies within package.json ranges aubr build # run a package.json script, auto-installing first if needed aube test # run the test script, auto-installing first if needed aube exec vitest # run a local binary, auto-installing first if needed aubx cowsay hi # run a local bin, or fetch one in a throwaway environment aube install # install only, for setup or lockfile/install modes aube ci # clean, frozen install for CI
You can also run scripts directly:
aube dev aube build aube lint
If the script exists in package.json, aube treats that as aube run <script>.
Shortcuts: aubr and aubx
aubr and aubx are multicall shims for aube run and aube dlx. They
share a binary with aube and dispatch purely on argv[0], so every flag
that works on the full command also works on the shim:
aubr build # aube run build aubx cowsay hi # aube dlx cowsay hi
aubr <name> runs a package script first, then falls back to a matching
local binary. aubx <name> prefers an installed local binary before fetching
into a throwaway environment; pass -p / --package to force the package
that should be installed for a one-off command.
The release archives ship all three binaries side by side; no extra setup is needed when you install aube via mise or the tarball.
CI
Use aube ci when the lockfile must be treated as the source of truth:
It removes node_modules, verifies the lockfile is fresh for the current package.json, then installs.
For Docker layers or workflows where you only want to update the lockfile:
aube install --lockfile-only
For production-only installs:
Workspaces
aube supports workspace projects and the workspace: protocol.
aube install -r
aube run test -r
aube add zod --filter @acme/apiIf a project already uses pnpm-workspace.yaml, aube can read and write it. New aube-first workspaces can use aube-workspace.yaml.
Lockfile Compatibility
| File | Reads | Writes in place |
|---|---|---|
aube-lock.yaml |
yes | yes |
pnpm-lock.yaml v9 |
yes | yes |
package-lock.json v2/v3 |
yes | yes |
npm-shrinkwrap.json |
yes | yes |
yarn.lock (v1 classic + v2+ berry) |
yes | yes |
bun.lock |
yes | yes |
aube is not compatible with every historical lockfile shape. Older pnpm v5/v6 lockfiles should be upgraded with pnpm before switching. Yarn PnP projects need to move to a node_modules linker first — aube writes node_modules, not .pnp.cjs.
When more than one lockfile exists, prefer keeping one canonical lockfile for the project so teammates and CI do not fight over dependency state.
Dependency Scripts
aube skips dependency lifecycle scripts by default. That protects installs from unexpected build steps in transitive packages.
To allow packages that need build scripts:
You can inspect packages whose scripts were skipped:
For approved packages, jailBuilds: true runs lifecycle scripts with a scrubbed env and temporary HOME. It defaults to false today and is planned to default to true in the next major version. Use package globs in jailBuildPermissions or jailBuildExclusions for packages that need specific env vars, paths, network, or a full opt-out.
Package Layout
aube uses an isolated node_modules layout. Packages are linked through node_modules/.aube/, and package files are stored once in $XDG_DATA_HOME/aube/store/ (defaulting to ~/.local/share/aube/store/).
That means:
- several projects with similar dependencies share package files and use less disk space;
- dependencies stay isolated, so phantom dependencies are harder to rely on accidentally;
- repeated installs can reuse package files already on disk.
Commands You May Recognize
aube supports the common package-manager surface:
aube list aube why react aube outdated aube audit aube pack aube publish aube link aube unlink aube config get registry aube store path aube store prune
Some pnpm commands are intentionally out of scope. Runtime-management commands such as env, runtime, setup, and self-update belong in tools like mise. Registry account helpers such as whoami, token, owner, search, pkg, and set-script are compatibility stubs that point you to the npm command instead.
Learn More
CI
Thanks to Namespace for providing CI for aube.
Star History
Contributors
Built by en.dev.
License
MIT