Carefully But Purposefully Oxidising Ubuntu

Last month I published Engineering Ubuntu For The Next 20 Years, which outlines four key themes for how I intend to evolve Ubuntu in the coming years. In this post, I’ll focus on “Modernisation”. There are many areas we could look to modernise in Ubuntu: we could focus on the graphical shell experience, the virtualisation stack, core system utilities, default shell utilities, etc.

Over the years, projects like GNU Coreutils have been instrumental in shaping the Unix-like experience that Ubuntu and other Linux distributions ship to millions of users. According to the GNU website:

The GNU Core Utilities are the basic file, shell and text manipulation utilities of the GNU operating system. These are the core utilities which are expected to exist on every operating system.

This package provides utilities which have become synonymous with Linux to many - the likes of ls, cp, and mv. In recent years, there has been an effort to reimplement this suite of tools in Rust, with the goal of reaching 100% compatibility with the existing tools. Similar projects, like sudo-rs, aim to replace key security-critical utilities with more modern, memory-safe alternatives.

Starting with Ubuntu 25.10, my goal is to adopt some of these modern implementations as the default. My immediate goal is to make uutils’ coreutils implementation the default in Ubuntu 25.10, and subsequently in our next Long Term Support (LTS) release, Ubuntu 26.04 LTS, if the conditions are right.

But… why?

Performance is a frequently cited rationale for “Rewrite it in Rust” projects. While performance is high on my list of priorities, it’s not the primary driver behind this change. These utilities are at the heart of the distribution - and it’s the enhanced resilience and safety that is more easily achieved with Rust ports that are most attractive to me.

The Rust language, its type system and its borrow checker (and its community!) work together to encourage developers to write safe, sound, resilient software. With added safety comes an increase in security guarantees, and with an increase in security comes an increase in overall resilience of the system - and where better to start than with the foundational tools that build the distribution?

I recently read an article about targeting foundational software with Rust in 2025. Among other things, the article asserts that “foundational software needs performance, reliability — and productivity”. If foundational software fails, so do all of the other layers built on top. If foundational packages have performance bottlenecks, they become a floor on the performance achievable by the layers above.

Ubuntu powers millions of devices around the world, from servers in your data centre, to safety critical systems in autonomous systems, so it behooves us to be absolutely certain we’re shipping the most resilient and trustworthy software we can.

There are lots of ways to achieve this: we can provide long term support for projects like Kubernetes, we can assure the code we write, and we can strive to achieve compliance with safety-centric standards, but another is by shipping software with the values of safety, soundness, correctness and resilience at their core.

That’s not to throw shade on the existing implementations, of course. Many of these tools have been stable for many years, quietly improving performance and fixing bugs. A lovely side benefit of working on newer implementations, is that it sometimes facilitates improvements in the original upstream projects, too!

I’ve written about my desire to increase the number of Ubuntu contributors, and I think projects like this will help. Rust may present a steeper learning curve than C in some ways, but by providing such a strong framework around the use of memory it also lowers the chances that a contributor accidentally commits potentially unsafe code.

Introducing oxidizr

I did my homework before writing this post. I wanted to see how easy it was for me to live with these newer implementations and get a sense of their readiness for prime-time within the distribution. I also wanted a means of toggling between implementations so that I could easily switch back should I run into incompatibilities - and so oxidizr was born!

oxidizr is a command-line utility for managing system experiments that replace traditional Unix utilities with modern Rust-based alternatives on Ubuntu systems.

The oxidizr utility enables you to quickly swap in and out newer implementations of certain packages with relatively low risk. It has the notion of Experiments, where each experiment is a package that already exists in the archive that can be swapped in as an alternative to the default.

Version 1.0.0 supports the following experiments:

How does it work?

Each experiment is subtly different since the paths of the utilities being replaced vary, but the process for enabling an experiment is generally:

  • Install the alternative package (e.g. apt install rust-coreutils)

  • For each binary shipped in the new package:

  • Lookup the default path for that utility (e.g which date)

  • Back up that file (e.g. cp /usr/bin/date /usr/bin/.date.oxidizr.bak)

  • Symlink the new implementation in place (e.g. ln -s /usr/bin/coreutils /usr/bin/date)

There is also the facility to “disable” an experiment, which does the reverse of the sequence above:

  • For each binary shipped in the new package:

  • Lookup the default path for the utility (e.g which date)

  • Check for and restore any backed up versions (e.g cp /usr/bin/.date.oxidizr.bak /usr/bin/date)

  • Uninstall the package (e.g. apt remove rust-coreutils)

Thereby returning the system back to its original state! The tool is covered by a suite of integration tests which illustrate this behaviour which you can find on Github

Get started

:warning: WARNING :warning:: oxidizr is an experimental tool to play with alternatives to foundational system utilities. It may cause a loss of data, or prevent your system from booting, so use with caution!

There are a couple of ways to get oxidizr on your system. If you already use cargo, you can do the following:

cargo install --git https://github.com/jnsgruk/oxidizr

Otherwise, you can download and install binary releases from Github:

# Download version 1.0.0 and extract to /usr/bin/oxidizr
curl -sL "https://github.com/jnsgruk/oxidizr/releases/download/v1.0.0/oxidizr_Linux_$(uname -m).tar.gz" | sudo tar -xvzf - -C /usr/bin oxidizr

Once installed you can invoke oxidizr to selectively enable/disable experiments. The default set of experiments in v1.0.0 is rust-coreutils and sudo-rs:

# Enable default experiments
sudo oxidizr enable

# Disable default experiments
sudo oxidizr disable

# Enable just coreutils
sudo oxidizr enable --experiments coreutils

# Enable all experiments without prompting with debug logging enabled
sudo oxidizr enable --all --yes -

# Disable all experiments without prompting
sudo oxidizr disable --all --yes

The tool should work on all versions of Ubuntu after 24.04 LTS - though the diffutils experiment is only available from Ubuntu 24.10 onward.

The tool itself is stable and well covered with unit and integration tests, but nonetheless I’d urge you to start with a test virtual machine or a machine that isn’t your production workstation or server! I’ve been running the coreutils and sudo-rs experiments for around 2 weeks now on my Ubuntu 24.10 machines and haven’t had many issues (more on that below…).

How to Help

If you’re interested in helping out on this mission, then I’d encourage you to play with the packages, either by installing them yourself or using oxidizr. Reply to the Discourse post with your experiences, file bugs and perhaps even dedicate some time to the relevant upstream projects to help with resolving bugs, implementing features or improving documentation, depending on your skill set.

You can also join us to discuss on our Matrix instance.

Next Steps

Earlier this week, I met with @sylvestre to discuss my proposal to make uutils coreutils the default in Ubuntu 25.10. I was pleased to hear that he feels the project is ready for that level of exposure, so now we just need to work out the specifics. The Ubuntu Foundations team is already working up a plan for next cycle.

There will certainly be a few rough edges we’ll need to work out. In my testing, for example, the only incompatibility I’ve come across is that the update-initramfs script for Ubuntu uses cp -Z to preserve selinux labels when copying files. The cp, mv and ls commands from uutils don’t yet support the -Z flag, but I think we’ve worked out a way to unblock that work going forward, both in the upstream and in the next release of Ubuntu.

I’m going to do some more digging on sudo-rs over the coming weeks, with a view to assessing a similar transition.

Summary

I’m really excited to see so much investment in the foundational utilities behind Linux. The uutils project seems to be picking up speed after their recent appearance at FOSDEM 2025, with efforts ongoing to rework procps, util-linux and more.

The sudo-rs project is now maintained by the Trifecta Tech Foundation, who are focused on “open infrastructure software in the public interest” . Their zlib-rs recently released v0.4.2, which appears to now be the fastest API-compatible zlib implementation. They’re also behind the Pendulum Project and ntpd-rs for memory-safe time synchronisation.

With Ubuntu, we’re in a position to drive awareness and adoption of these modern equivalents by making them either trivially available, or the default implementation for the world’s most deployed Linux distribution.

We will need to do so carefully, and be willing to scale back on the ambition where appropriate to avoid diluting the promise of stability and reliability that the Ubuntu LTS releases have become known for, but I’m confident that we can make progress on these topics over the coming months.

30 Likes

Very exciting news. Worth at least trying out.

3 Likes

Why not leverage the pre-existing alternatives system that Ubuntu inherited from Debian?

It’s already a mature tool for selecting between different implementations of the same thing, and is already used by Ubuntu commands such as parallel which are present in both moreutils and parallel packages.

That way deleting the Rust package would automatically switch back to the GNU implementation without requiring the user to mess with backups, and making it impossible to leave the system without foundational tools at all as long as at least one implementation is installed.

8 Likes

I agree that the alternatives system may be considered in this context as a short-term helper.

Long-term, my concern would be that this may somewhat muddy the picture for which packages need substantive fixes. If it is extremely easy to just revert, what is the benefit to switching?

I suspect these precise details and more will be worked out over time. In the meantime, it may be too early to make a fully-qualified judgement.

Where some people see rust, some of us see a nice patina. On with oxidizr!

That’s not quite true. In the case of parallel those are diversions, the uglier cousin of alternatives. But I do agree that update-alternatives(1) sounds like the perfect fit for the described purpose.

2 Likes

Hi, Rust dev here who uses Ubuntu as part of my daily workflow. When I want to learn how a particular coreutils command works, I now go to the Rust implementation first, so I’m really excited to see this happen!

I’m curious if there are any use cases or plans to support overrides scoped by command, directory or shell, similar to rustup. This necessitates a proxy binary approach (as opposed to symlinks) and I believe is not something update-alternatives can do at the moment.

The alternatives system doesn’t work here because the existing package would need to cooperate, and that makes exploring awkward. Diversions would work, and be preserved across upgrades, but are basically the same thing otherwise (renaming the files).

As for doing this in the archive, see below…

I do not believe we should allow users to select between Rust and non-Rust versions at a per-command level, this will make the resulting systems hard to support - you never know which version the user picked, and these are very low-level tools and if you are looking at bugs 100 layers of indirection up, you might not realize the user is using a different version of a given command.

What I believe we will end up needing to do is roughly:

  • Rename coreutils to gnu-coreutils, add Replaces/Provides/Conflicts: coreutils
  • Add a new transitional package coreutils that Depends: rust-coreutils

You can also change GNU coreutils to build with a g prefix so you get gsha256sum and friends and it would be co-installable (but then if you wanted to fully switch back, that would need yet another package with a symlink farm).

7 Likes

I am looking forward to testing as seeing these innovations in future ubuntu builds.

1 Like

Hello!

Does this actually mean that Ubuntu is actually kind of heading towards GNUlessness…? I know there are Linux distros without GNU components already, so.

Don’t read too much into the licensing of this change - this is not symbolic of any pointed move away from GNU components - it’s literally just about replacing coreutils with a more modern equivalent.

Sure, the license is different, and it’s a consideration, but it’s by no means a driver in the decision making.

Hope that helps!

3 Likes

Sure it helped. Just a thought about a possible transition.

I hear that glibc (for example) has been known to cause problems with Linux (for example breaking anti cheats and not prioritizing compatibility damages on Linux).

How does this work on non-x86/non-Arm versions of Ubuntu?

AIUI the LLVM Rust toolchain is still a little immature and code generation for other architectures is lacking. Ubuntu also supports ppc64le and s390 architectures:

https://help.ubuntu.com/community/SupportedArchitectures

Are you able to built binaries from Rust on them? I am not sure if interim releases are built for these other CPU architectures, but if so, are you simply hoping that Rust’s LLVM toolchain works well for those targets by 2026?

1 Like

Upstream here!

LLVM Rust toolchain is still a little immature and code generation for other architectures is lacking

Do you have bug reports? Firefox has been shipping on these architectures with Rust code for years now.

We have been building Rust-coreutils on Debian & Ubuntu for a few years too:
https://buildd.debian.org/status/package.php?p=rust-coreutils
https://launchpad.net/ubuntu/+source/rust-coreutils/0.0.27-3

4 Likes

OK, fair enough. I sit corrected.

As for a source: no, no bug reports, but x86-32/x86-64 and Arm64 are the only “tier 1” architectures according to the Rust project’s own docs:

https://doc.rust-lang.org/beta/rustc/platform-support.html

When I said “lacking” I did not mean “absent” but “not of comparable quality”. As that docs page says:

«
Bugs are possible in all code, but the level of quality control for these targets is likely to be lower.
»

And what about RISC-V?

1 Like

By the way, sooner or later we will try to oxidise applications which print, and therefore I have posted a GSOC project for Rust bindings for libcups. But to really be able to run it we need 1 or 2 mentors with experience in Rust, ideally even in creating bindings for libraries. Are there any volunteers here?

1 Like

What about locale support?

From what I am seeing, locale support in uutils is quite incomplete. Is this going to be addressed before adopting uutils? Otherwise it will cause a lot of breakage for non-English users.

2 Likes

Yes, we will be working with the uutils maintainers on a path forward for this. Stay tuned!

3 Likes

You’re switching from a GPL licensed core utils to an MIT licensed core utils. I cannot support this decision. If this goes through, I will migrate all servers and workstations that I admin to Fedora/Rocky.

The GPL ensures that contributions to essential utilities remain accessible to all, preventing proprietary forks that benefit corporations while sidelining the community. Unlike the MIT license, which allows unrestricted appropriation, the GPL guarantees reciprocity: if an entity benefits from community-driven software, it must contribute back. Deciding to abandon core utilities is a slap in the face to everyone who has contributed to your ecosystem.

By moving to an MIT-licensed core, Canonical is effectively inviting large corporations to take advantage of community labour without contributing improvements. History has shown that when companies extract value without reinvesting, the long-term viability of open-source projects suffers. Given the increasing trend of corporate appropriation of FOSS, this decision is particularly concerning.

This decision seems to align with a broader trend of companies deprecating GPL software in favour of more permissively licensed alternatives, often under the guise of “modernization.” However, the real-world impact is clear: free software is increasingly co-opted into proprietary ecosystems, weakening the principles that made Linux successful.

To be clear, I adore Rust, or at least, the idea of memory safety and a rewrite of all code into a safer, better implementation. I support its adoption in the kernel and would support any GPL-licensed rewrite of the core utils. It tears to me in two that the biggest oxidized project is MIT licensed and is rewriting GPL code.

4 Likes