github nubjs/nub v0.8.0
Nub 0.8.0

3 hours ago

Nub 0.8.0 reworks environment-file configuration, ships a round of package-manager correctness fixes, and adds garbage collection for the package store.

Important

Two changes are worth knowing before upgrading:

  • File paths in envFile now go in an array — "envFile": [".env"]. A bare string path is an error that names the fix. (#735)
  • The first install after upgrading relinks each warm tree once, because hidden-hoist link ordering changed. (#775)

Breaking changes

File paths in envFile go in an array. "envFile": ".env" is now an error naming [".env"]; a string value is reserved for mode names, and "varlock" is the only one. This makes envFile consistent with the other list-valued config fields. (#735)

A declared envFile now displaces a .env.schema hand-over, at every scope. A .env.schema file decides the environment only when no envFile is declared. Previously the two together were a hard error, and envFile: false in a schema project loaded the schema anyway. Now declared intent wins: envFile: false (or --no-env-file) loads nothing, an envFile list loads those files, and envFile: "varlock" keeps the hand-over explicitly. This applies to a global-scope envFile too, so a machine-wide envFile: false empties a schema project unless the project declares "varlock". (#735, #774)

An unreadable tsconfig.json now refuses the run. A project tsconfig whose extends target is missing previously ran under options its author never wrote — extends is where strict, target, and path aliases usually live. Nub now stops with the read error, as tsc does (TS5083). Fix the config, or run with --node. A dependency's own unreadable tsconfig is still salvaged rather than fatal. (#778, #768)

Another package manager's config no longer directs the node_modules layout. The layout is configured in nub.jsonc (install.linker, install.publicHoist) under every project identity. The last two branded exceptions are gone: pnpm 11's pnpm-workspace.yaml layout keys are no longer read, and npm's install-strategy=nested no longer aborts the install. (#698)

Version-gated feature flags moved out of NODE_OPTIONS. NODE_OPTIONS is inherited by the whole process subtree, and flags matched to the host Node aborted any descendant on an older Node — Electron apps exited at startup. Feature flags now ride argv instead. Cost: a tool that spawns Node by absolute path (bypassing the shim) loses the version-gated features, though it keeps the preload and source-map remapping. (#777)

Package manager

Area What changed PR
Optional dependencies A build failure in an optionalDependencies entry skips the package with a warning instead of failing the install, matching npm and pnpm. #737
Store maintenance nub store prune now garbage-collects the global virtual store and extracted-tree tiers, not just the content store. Installs register the project with the store; a project whose last install predates 0.8.0 registers on its next install. #720
nub outdated minimumReleaseAge now applies to both reported columns, so the report no longer offers upgrades nub update would decline. A held version is marked with the time it becomes installable, and a project whose only pending upgrade is held exits 0. #743
Release-age policy A frozen install revalidates the release policy only when the age gate actually moved. #710
Relocated stores A store-dir override now moves every store tier together, so phantom-dependency protection keeps working and the machine's default store stays untouched. #644
.bin wrappers A package whose bin shares its interpreter's name (for example the node npm package) no longer produces a wrapper that resolves to itself — nub install node used to hang. #741
Workspaces Workspace aliases and relative-path workspace specs resolve. #717
Workspaces A member-scoped nub update resolves in the workspace-root frame. #754
Workspaces The disk-materialize eject applies in workspace projects too. #736
Workspaces nub config init writes nub.jsonc at the workspace root. #714
Lockfiles An empty importer reads as drift, not as a specifier-less lockfile format. #763
Linker Hidden-hoist names are claimed shallowest-first, matching pnpm's depth ordering — 1.0.0 no longer beats 2.0.0 on lexicographic accident. #775
Resolution Peer-context convergence is sized by graph. #716
Registry A stalled packument fetch is bounded and surfaced instead of hanging the install. #723
Configuration NUB_CACHE_DIR moves the engine cache, and nub config get/list report values set through the environment. #740
Configuration A settings default with a namespace resolves against the active embedder. #780
Fresh installs The shim directories honor XDG_DATA_HOME on a fresh install; an existing ~/.nub install keeps its path. #752
Source builds A source build (Homebrew and friends) now fails loudly when a build prerequisite is missing instead of shipping a quietly degraded binary. #761

Runtime

Area What changed PR
import defer Deferred module evaluation is enabled on Node 26.4+, where Node wires the defer phase through. #770
Loaders A user loader delivered through NODE_OPTIONS is seen by the CommonJS-sync guard. #742
fetch cache Cache-evict builtins load synchronously, closing a startup race. #707
Types @nubjs/types covers the six polyfilled proposals an es2024 lib can't reach. #734
Windows nub.exe reserves an 8 MB main-thread stack, matching node.exe. #701

CLI

  • A help flag after the verb works in the pm and node command groups. (#739)
  • Ctrl-C signals every concurrent child of nub run, and --color takes effect. (#744)

What's Changed

  • fix(config): write nub.jsonc at the workspace root by @colinhacks in #714
  • pm: allow deep peer-context convergence by @colinhacks in #716
  • cli: reserve an 8 MB main-thread stack for nub.exe on Windows by @pullfrog[bot] in #701
  • runtime: fetch cache-evict builtins synchronously by @pullfrog[bot] in #707
  • fix(pm): make layout nub's own axis, with nub.jsonc as its canonical surface by @colinhacks in #698
  • fix(pm): resolve workspace aliases and relative-path workspace specs by @colinhacks in #717
  • fix(registry): bound and surface a stalled packument fetch by @colinhacks in #723
  • types: cover the six polyfilled proposals an es2024 lib can't reach by @colinhacks in #734
  • runtime: let envFile take precedence over the Varlock hand-over by @colinhacks in #735
  • wiki: adopt lat.md as the corpus knowledge graph by @colinhacks in #725
  • fix(pm): apply the disk-materialize eject in workspace projects too by @colinhacks in #736
  • fix(runtime): see a NODE_OPTIONS-delivered user loader in the commonjs-sync guard by @colinhacks in #742
  • fix(pm): move the phantom sidecar tier with a store-dir override by @jdalton in #644
  • cli: parse a help flag after the verb in the pm and node groups by @colinhacks in #739
  • Harden source builds of nub against silent degradation by @colinhacks in #761
  • docs: correct the env-precedence attribution — the ecosystem is split, not a consensus by @colinhacks in #762
  • fix(linker): never let a .bin wrapper resolve to itself by @colinhacks in #741
  • lockfile: treat an empty importer as drift, not as a specifier-less format by @colinhacks in #763
  • pm: garbage-collect the virtual store and extracted-tree tiers by @colinhacks in #720
  • run: signal every concurrent child on Ctrl-C, and make --color take effect by @colinhacks in #744
  • fix(tsconfig): keep the local compilerOptions when an extends target is missing by @colinhacks in #768
  • fix(pm): resolve a member-scoped update in the workspace-root frame by @colinhacks in #754
  • fix(install): an optional dependency's build failure no longer fails the install by @colinhacks in #737
  • fix(install): only revalidate release policy when the age gate moved by @candrewlee14 in #710
  • outdated: apply minimumReleaseAge to both reported versions by @colinhacks in #743
  • pm: honor NUB_CACHE_DIR for the engine cache, and report the env tier in nub config by @colinhacks in #740
  • runtime: let a global envFile displace a .env.schema too by @colinhacks in #774
  • linker: claim hidden-hoist names shallowest-first, matching pnpm's depth ordering by @colinhacks in #775
  • fix(tsconfig): refuse the run when the project's tsconfig cannot be read by @colinhacks in #778
  • pm/node: honor XDG_DATA_HOME for the shim dirs on a fresh install by @colinhacks in #752
  • node: auto-unflag import defer on Node 26.4+ by @colinhacks in #770
  • settings: resolve the namespace in a default against the active embedder by @colinhacks in #780
  • node: keep version-gated flags out of NODE_OPTIONS so Electron survives by @colinhacks in #777
  • tests: make recursive clones skip the node-suite submodule by @colinhacks in #791

New Contributors

Full Changelog: v0.7.5...v0.8.0

Don't miss a new nub release

NewReleases is sending notifications on new releases.