Use of swappable -bin packages for managing NodeJS symlinks
Summary
We aim to move away from manual management of /usr/bin/node, /usr/bin/npm, and similar symlinks to leveraging swappable nodejsXX-bin, nodejsXX-npm-bin packages.
Owners
- Name: Andrei Radchenko
- Email: aradchen@redhat.com
- Name: Jan Stanek
- Email: jstanek@redhat.com
- Name: Tomas Juhasz
- Email: tjuhasz@redhat.com
Current status
- Targeted release: Fedora Linux 44
- Last updated: 2026-02-17
- Announced
- Discussion thread
- FESCo issue: #3452
- Tracker bug: #2394090
- Release notes tracker: #262
Detailed Description
This is a part of a larger iteration in a way we package NodeJS for Fedora and RHEL. The other parts are Changes/NodejsNodeModulesPath and Changes/NodeJSMetapackages. This change deals specifically with the management of the non-versioned symlinks in system paths.
Currently, the NodeJS packages (streams) provided in Fedora are all installable in parallel, by virtue of moving any potentially conflicting bits into versioned equivalents and/or versioned directories. For one example of many:
%install
mv %{buildroot}%{_bindir}/node %{buildroot}%{_bindir}/node-%{node_version_major}
...
One of the streams is designed as the "default" one, and that stream then ships manually created non-versioned symlinks to the renamed paths:
%if 0%{nodejs_is_default}
ln -srf %{buildroot}%{_bindir}/node-%{node_version_major} %{buildroot}%{_bindir}/node
...
%endif
By using bin packages, we can iterate on this idea and gain several benefits outlined below.
Feedback
-
Dan Čermák and Vitaly Zaitsev pointed out in the mailing thread that
update-alternativesdoes not really work on immutable systems, such as Silverblue.Vitaly then offered an idea to introduce "swappable" packages, such as
nodejs22-binandnodejs24-bin, that would contain the symlinks and could be swappable viadnf swap nodejs22-bin nodejs24-bin. Leveraging weak dependencies and the fact that "If adding the package would lead to an error dnf will by default ignore the dependency" (source), this looks like a viable alternative.We'll try to experiment with it in a dedicated COPR and see what we can get working.
The testing COPR and the corresponding source code branch is now available. We also have a repository for testing scenarios related to this approach; feel free to suggest more of those!
Benefit to Fedora
- No matter which stream you install, you'll always have
/usr/bin/nodeand other non-versioned names available. The versioned names will be also present, if you want to be specific in your scripts. - There is no "official Fedora endorsement" on which NodeJS stream should be "best" or "default"; if you as a system administrator have multiple streams installed, the decision of which should be the default is up to you.
The second item will also give us the maintainers greater freedom in introducing new streams and obsoleting the old ones without worrying too much about how to switch the "default" in the middle of the distribution life cycle. This is not a big pain point for Fedora, where the length of the life of a single version matches the length of upstream NodeJS LTO support pretty closely, but becomes much more important in longer-living downstream distributions (e.g. RHEL).
Scope
- Proposal owners:
- Port the manual symlink creation and management to -bin packages.
- Ensure the streams behave consistently and no conflict is introduced.
User Experience
Users will be able to install any number of streams and switch where /usr/bin/node points by using dnf swap feature:
# dnf install nodejs22 nodejs24 Package Arch Version Repository Size Installing: nodejs22 x86_64 2:22.17.1-3.fc43 copr:copr.fedorainfracloud.org:jstanek:nodejs-bin-alternatives 293.6 KiB nodejs24 x86_64 1:24.4.1-8.fc43 copr:copr.fedorainfracloud.org:jstanek:nodejs-bin-alternatives 297.7 KiB Installing dependencies: ... nodejs22-npm-bin noarch 2:22.17.1-3.fc43 copr:copr.fedorainfracloud.org:jstanek:nodejs-bin-alternatives 12.8 KiB ... Installing weak dependencies: nodejs22-bin noarch 2:22.17.1-3.fc43 copr:copr.fedorainfracloud.org:jstanek:nodejs-bin-alternatives 138.8 KiB ...
# dnf swap --allowerasing nodejs22-bin nodejs24-bin Package Arch Version Repository Size Removing: nodejs22-bin noarch 2:22.17.1-3.fc43 copr:copr.fedorainfracloud.org:jstanek:nodejs-bin-alternatives 138.8 KiB Removing dependent packages: nodejs22-npm-bin noarch 2:22.17.1-3.fc43 copr:copr.fedorainfracloud.org:jstanek:nodejs-bin-alternatives 12.8 KiB Installing: nodejs24-bin noarch 1:24.4.1-8.fc43 copr:copr.fedorainfracloud.org:jstanek:nodejs-bin-alternatives 138.8 KiB Installing dependencies: nodejs24-npm-bin noarch 1:24.4.1-8.fc43 copr:copr.fedorainfracloud.org:jstanek:nodejs-bin-alternatives 12.8 KiB Transaction Summary: Installing: 2 packages Removing: 2 packages
Users will need to take greater care of what their symlinks points to; some of the update scenarios might even result in removing the symlinks altogether. For example, removing a stream from which the current -bin packages originate (including on i.e. Fedora system-upgrade) will not install a replacement automatically:
# dnf install nodejs22 nodejs24 ... same result as above # ls -l /usr/bin/node lrwxrwxrwx. 1 root root 7 čec 28 02:00 /usr/bin/node -> node-22 # dnf remove nodejs22 Package Arch Version Repository Size Removing: nodejs22 x86_64 2:22.17.1-3.fc43 copr:copr.fedorainfracloud.org:jstanek:nodejs-bin-alternatives 293.6 KiB Removing unused dependencies: nodejs22-bin noarch 2:22.17.1-3.fc43 copr:copr.fedorainfracloud.org:jstanek:nodejs-bin-alternatives 138.8 KiB nodejs22-docs noarch 2:22.17.1-3.fc43 copr:copr.fedorainfracloud.org:jstanek:nodejs-bin-alternatives 48.8 MiB nodejs22-full-i18n x86_64 2:22.17.1-3.fc43 copr:copr.fedorainfracloud.org:jstanek:nodejs-bin-alternatives 30.4 MiB nodejs22-libs x86_64 2:22.17.1-3.fc43 copr:copr.fedorainfracloud.org:jstanek:nodejs-bin-alternatives 79.2 MiB nodejs22-npm noarch 1:10.9.2-2.22.17.1.3.fc43 copr:copr.fedorainfracloud.org:jstanek:nodejs-bin-alternatives 9.3 MiB nodejs22-npm-bin noarch 2:22.17.1-3.fc43 copr:copr.fedorainfracloud.org:jstanek:nodejs-bin-alternatives 12.8 KiB Transaction Summary: Removing: 7 packages # ls -l /usr/bin/node ls: cannot access '/usr/bin/node': No such file or directory
When using nodejs and/or npm as a build-time dependency, care needs to be taken to specify that the -bin package should be installed as well. The suggested way to do this would be to use BuildRequires: <main package>, <unversioned_path>…; e.g.:
# Do not care which stream will get installed; use metapackage BuildRequires: nodejs, /usr/bin/node, /usr/bin/npm # Needs a specific nodejs major version/stream, but wants unversioned commands BuildRequires: nodejs24, /usr/bin/node, /usr/bin/npm
Dependencies
- Should not cause any problems to dependant packages.
Contingency Plan
- Contingency mechanism: Revert back to manual symlink management and go back to the design phase.
- Contingency deadline: Beta Freeze.
- Blocks release? We aim to do the rebuilds in Koji side tag and merge it atomically; so NO.
Documentation
- This is a downstream change; this page is the initial documentation.
- Fedora Alternatives
Release Notes
The packages nodejs24-bin, nodejs22-bin, and nodejs20-bin, along with their npm counterparts nodejs{24,22,20}-npm-bin are currently available.
Depending on which -bin packages are installed - node and npm commands will be configured to be pointing to different NodeJS versions.
Use # dnf install nodejs24-bin or equivalent to install node command that will run NodeJS v24.x. Use # dnf swap --allowerasing nodejs24-bin nodejs22-bin to change the NodeJS version used.
