Parallel downloads, opal add and opal remove, and an install that shows what it is doing. No opal.lock format change.
To install Opal v0.4.0
curl -fsSL https://raw.githubusercontent.com/saintparish4/opal/master/install.sh | OPAL_VERSION=v0.4.0 bash
What's new
opal add,opal remove(rm,uninstall), andopal install <pkg>changepackage.json,opal.lock, andnode_modulesin one step.-Dand-Ochoose the dependency group, and-Esaves the exact version. A version or range you typed is saved as typed; a bare name or a tag saves a^range on what was installed.package.jsonkeeps its formatting when Opal edits it, and nothing is written unless the change resolves.opal removeof a name that isn't a dependency is an error, not a silent success.opal installopens by naming the build it came from:opal install v0.4.0 (<commit>).- Resolving shows a live
[settled/known]package count on a terminal, and prints the final count once when piped. - Downloads show one bar per tarball in flight, with its name and bytes of its total, under a line counting packages.
- The project's own dependencies that a run added are listed as
+ name@versionabove the summary, five at most with the rest counted.
Changed
- Packages download 16 at a time instead of one at a time, and one package's files are stored on several threads. A first install of a 364-package Next.js app takes about 24s where v0.3.0 took about 2m on the same machine, in separate sessions. Resolution is still sequential, so the lockfile it writes is the same.
- A re-resolve keeps what is locked. When
package.jsonchanges, Opal starts from the existingopal.lock, so adding or removing one package no longer moves the rest of the tree to newer versions. This applies to a hand edit followed byopal installtoo. Deleteopal.lockto re-resolve from nothing. - The summary's total is in brackets,
364 packages installed [26.5s], and result lines are coloured on a terminal. Piped output has no colour and no stage lines: the header, the resolve count, and the result. A script that reads Opal's output should check it against the new format. - The Linux binaries are built on Ubuntu 22.04 and need glibc 2.34 again, so they run on Ubuntu 22.04, Debian 12, and RHEL 9.
- Dependencies: rustls 0.23.45 for RUSTSEC-2026-0285, oxc 0.152.0, and patch updates for blake3, flate2, ureq, clap, thiserror, and console.
Fixed
install.shno longer installs a binary that can't run on the machine. It runs the new binary once and stops, leaving any existing install in place, if it doesn't start.- A killed install could leave a
write-<pid>-….tmpfile in the project folder, and nothing removed it. The two files Opal writes into a project now go throughopal.lock.tmpandpackage.json.opal-tmp, which the next run clears. Files already left by an earlier version are not removed.
Known issues
opal addandopal removeask the registry about every package in the tree, not only the one being changed. On a Next.js app that is about half a second when the metadata was fetched in the last five minutes, about 2s when it is older, and 5–7s when none is cached, as on a machine that installed from a lockfile. A fix for the second case is planned for 0.4.1.
Full Changelog: https://github.com/saintparish4/opal/compare/v0.3.1...v0.4.0