Skip to content

Nub 0.11.0

Latest

Choose a tag to compare

@github-actions github-actions released this 13 Nov 00:51
8f4e9be

Nub 0.11.0 preloads TypeScript 7.1 content mappers, adds nub add --save-types, installs one copy of a package where pnpm does, and removes the canary channel. It also fixes a broad set of correctness bugs in the runtime, the package manager and nub run.

Important

Five changes can surface in an existing project:

  • The canary channel is gone. nub upgrade --canary and --stable are unknown flags, and install.sh and install.ps1 no longer accept canary. An existing canary install keeps working, and nub upgrade --stable still moves it to a release (#1102)
  • A lockfile missing a required entry is broken. nub ci and nub install --frozen-lockfile exit 16 and name the entry, and a plain nub install repairs it. Both exited 0 and left a tree that could not load (#1105)
  • nub add <pkg>@<tag> saves a prerelease exact, as pnpm does. A stable tag still saves with ^ (#1096)
  • Some lockfiles change once. A local or URL package keeps its peers on its key, and a tree that held duplicate copies of a package collapses them on its next fresh resolve (#1093, #1089)
  • The first install after upgrading relinks once, because the dependency scan's cache was reset (#1113)

Content mappers

TypeScript 7.1's content mappers type-check other file types, but TypeScript never runs them. Nub now preloads the ./register export of every package the tsconfig lists, with no --import and no nub.jsonc entry (#1082).

{
  // ...
  "contentMappers": [
    { "package": "motherload", "extensions": [".toml", ".yaml"] }
  ]
}
import config from "./config.yaml"; // loaded by motherload/register

extends and references are followed, the longest extension answers first, and an entry's options reach its register in CONTENT_MAPPER_OPTIONS.

Type packages on add

nub add --save-types <pkg> also saves the DefinitelyTyped package to devDependencies for each registry package whose installed version ships no types, picking the newest @types release on that package's major (#1110, fixes #1016).

nub add --save-types express

A package with no @types release, or only a deprecated stub, prints skipped @types/<name>: <reason>. An @types entry the project already lists is kept.

Package manager

Area What changed Link
Duplicate copies A package installs once where pnpm installs it once. The Nuxt starter went from 17 duplicate copies to 0, and workspace members no longer get two module objects for one package. #1089
Peers of local packages A file:, URL or git package consumed with two sets of peers loads the right peer after a lockfile install. One entry served both consumers, with no error. #1093
Edges to workspace members A registry package whose peer a workspace member satisfies links to the member, as pnpm writes it. The install succeeded and require failed with Cannot find module. #1081
Local packages from a pnpm lockfile file: and link: packages read back from nub.lock or pnpm-lock.yaml get the graph a fresh resolve gives. A root peer pinned to a tarball URL no longer fails every resolve after the first with ERR_NUB_BLOCKED_EXOTIC_SUBDEP. #1072, #1109, fixes #1108
Failed adds A failed nub add or nub install <pkg> restores package.json, the lockfiles and the workspace yaml. The new dependency stayed in package.json. #1111
--fix-lockfile nub install --fix-lockfile rewrites the lockfile, keeping its pinned versions. It repairs a package-lock.json written with the dev-optional flags 0.10.0 fixed. #1091, refs #1087
bun.lock local paths A member's file: directory and a hoisted tarball install under nub ci and --frozen-lockfile, and a bun.lock Nub writes spells local packages as bun does, which bun install --frozen-lockfile accepts. #1112
Filtered installs nub install --prod, --dev and --no-optional download only the dependencies they link. Every package in the graph was downloaded into the store. #1121, fixes #1120
pnpm-workspace.yaml A # comment after a pattern or after packages:, and the flow form packages: ['a/*', 'b/*'], are read. Each found no workspace members. #1113
Repeated .npmrc keys The last script-shell, ignore-scripts or node-mirror:release wins, as in npm. The first won. #1113
packageManager paths A version that walks out of its package, such as pnpm@../npm/10.9.0, fails to resolve. It installed the other package into the store under the requested name. #1113
nub pm use nub pm use nub keeps catalog and nohoist from an object-form workspaces, and nub pm use pnpm keeps the other keys under workspaces. #1113
Dependency scan require('buffer/'), a directory with a main, a template-literal require and import x = require() resolve as Node resolves them, and .d.mts and .d.cts files are not scanned. #1113

Running files

Area What changed Link
Node's permission model nub --permission --allow-addons app.js starts, --permission in NODE_OPTIONS gets the same --allow-addons message as the flag, and the last of --permission and --no-permission decides, as in Node. The first two failed with ERR_ACCESS_DENIED on Nub's own runtime. #1113
Flags after the entry nub app.js --permission passes --permission to the program. It was read as Node's own flag. #1113
.env PASSWORD="foo\$bar" loads foo$bar, and a variable that refers back to itself, such as A=x$A, expands that reference to nothing. #1113
Node version pins engines.node: "20.11.0 || 22.1.0" matches those exact versions, a v in a range is read as node-semver reads it, and a # comment in .nvmrc or .node-version is read as nvm reads it. #1113
tsx as a loader --import tsx runs on Node 24.11.1, 25.0 and 25.1. It failed with ERR_METHOD_NOT_IMPLEMENTED. #1113
Native addon A panic in Nub's addon throws a catchable error. It aborted the process. #1113
nub node install With Nub's node shim on PATH, it installs only the version asked for. #1113
Home-folder projects A stray package.json and node_modules in the home folder no longer hang every run under it on macOS. The pre-run dependency scan skips a project rooted at the home folder and gives up after 500 ms. #1117
Windows scripts Script bodies and lifecycle scripts keep backslashes in environment values, so os.homedir() reads C:\Users\… inside a script and Nub's preload is injected once. #1107

Runtime

Area What changed Link
Node 27 language changes Intl.Locale#variants is polyfilled and typed in @nubjs/types. Iterator.zip and Iterator.zipKeyed close every input on an early return or a failure. On Node 27, its native versions of these are used. A Test262 subset now runs against the polyfills. #1097
Polyfill shapes Promise.withResolvers, Iterator.from, URL.parse, the Uint8Array base64 methods and 23 others have no prototype and refuse new, like the builtins. Float16Array and URLPattern are non-enumerable, RegExp.escape escapes lone surrogates, and ErrorEvent before Node 25 reads its fields from prototype getters. #1113
Replaced built-ins Nub's runtime helpers keep working after application code replaces a global or a prototype method. #1099
--experimental-web-worker With Node's own Worker global enabled, Nub keeps it and its worker scope instead of installing its polyfill. #1098
Worker nub --max-old-space-size=4096 app.mjs no longer makes the global Worker throw ERR_WORKER_INVALID_EXEC_ARGV, and a worker that throws null delivers its error event. #1106, #1113
A foreign registerHooks On Node 22.15 to 24.11, an --import that calls module.registerHooks, such as amaro/strip, no longer makes every CommonJS file throw ERR_INVALID_RETURN_PROPERTY_VALUE. #1101

Scripts and config

Area What changed Link
nub exec -r A shell-script bin runs in each member's directory. It ran in the invoking directory. #1113
--sequential, --parallel A regex run outside any workspace runs that package's scripts, as pnpm 9, 10 and 11 do. #1113
Flags before the verb --cwd=<dir>, --if-present and --reporter-hide-prefix are accepted there. They failed with node: bad option. #1113
PATH An entry that is not UTF-8 no longer leaves scripts with an empty PATH. #1113
nub config set Writes through a symlinked nub.jsonc instead of replacing the link. #1113
nub init Skips git init in a subfolder of a repository. #1113
nubx prompt Answering Never beside dlx.consent: "prompt" stays off. #1113

Install and upgrade

Area What changed Link
Canary channel Removed, with nub upgrade --canary and --stable. nub-version: canary in the setup-node action no longer installs. #1102
install.sh Detects musl through ldd on systems other than Alpine. #1113
setup-node action Reads .tool-versions and an absolute package.json as a node-version-file, and .nvmrc and .node-version as nvm reads them. #1113

Security

Nub's Rust network clients reject the compromised eMudhra certificate chains (#1019). JavaScript running under Node still relies on Node's own certificate store.

Docs, testing and internals

  • The repository has a CONTRIBUTING.md, a SECURITY.md and a code of conduct (#1116, #1115).
  • The test suite runs on Node 26 (#1020), and the version-tier tests install the Node versions they skipped without (#1114).
  • The integration tests find the nub binary through Cargo, which keeps test executables in a different directory from Rust 1.100 (#1113).
  • Seven slower pull-request workflows run on a ci-full label (#1104).
  • Releases build with the current stable Rust (86c1817).

What's Changed

  • pm: install one copy of a package where pnpm does by @colinhacks in #1089
  • compile: resolve each --external from the module that imported it by @colinhacks in #1092
  • lockfile: read local packages back from a pnpm lockfile as a fresh resolve stores them by @colinhacks in #1072
  • release: retry release-asset reads while reconciling by @colinhacks in #1095
  • pm: save a prerelease dist-tag exact on add by @colinhacks in #1096
  • pm: give a registry package's edge to a workspace member a package to land on by @colinhacks in #1081
  • lockfile: keep a local or URL package's peers on its key by @colinhacks in #1093
  • test: migrate script units to erasable TypeScript and pinned tsrs checks by @jdalton in #1100
  • runtime: preserve native Web Workers and avoid fallback Blob copies by @jdalton in #1098
  • runtime: use captured built-ins in shared CJS helpers by @jdalton in #1099
  • pm: accept --fix-lockfile on nub install by @colinhacks in #1091
  • release: remove the nightly canary and the canary channel by @colinhacks in #1102
  • runtime: align polyfills with Node 27 Alpha and add Test262 coverage by @jdalton in #1097
  • runtime: keep CommonJS loading under a foreign registerHooks on the async tier by @colinhacks in #1101
  • ci: move seven slower workflows behind a ci-full label by @colinhacks in #1104
  • compile: name a store package by the package in regions and source maps by @colinhacks in #1103
  • compile: give untraced workers the compiled worker scope by @colinhacks in #1106
  • pm: treat a lockfile missing a required entry as broken by @colinhacks in #1105
  • runtime: preload ./register for tsconfig contentMappers packages by @colinhacks in #1082
  • run: start the Windows script shell with busybox -X by @colinhacks in #1107
  • resolver: test a peer the root pins to a URL across lockfile reuse by @colinhacks in #1109
  • pm: restore package.json and the lockfile when an add fails by @colinhacks in #1111
  • fix(deps): distrust compromised eMudhra certificate chains by @jdalton in #1019
  • pm: add --save-types to nub add by @abappi19 in #1110
  • ci: run the test suite on Node 26 by @jdalton in #1020
  • pm: read and write bun.lock local paths the way bun does by @colinhacks in #1112
  • aube: give the security scanner tests a 300s budget by @colinhacks in #1119
  • run: keep the pre-run phantom scan out of the home folder by @colinhacks in #1117
  • ci: install the Node versions version_tiers skipped without by @colinhacks in #1114
  • docs: add CONTRIBUTING.md and SECURITY.md by @abappi19 in #1116
  • ci: target the image's Node major in the musl native-islands leg by @colinhacks in #1123
  • Add Contributor Covenant Code of Conduct by @abappi19 in #1115
  • runtime, cli, pm, compile: fix correctness bugs and remove dead code by @colinhacks in #1113
  • pm: fetch only the selected dependencies on a filtered install by @colinhacks in #1121

New Contributors

Full Changelog: v0.10.0...v0.11.0