Fish Shell 4.0 Released: Core Rewritten in Rust with No User Impact

BigGo Editorial Team
Fish Shell 4.0 Released: Core Rewritten in Rust with No User Impact

The popular Fish shell has reached version 4.0.0, marking a significant milestone with its core code being completely rewritten in Rust. Released on February 27, 2025, this major update represents nearly two years of development work spanning over 2,600 commits by more than 200 contributors.

The Rust Rewrite

The most notable change in Fish 4.0 is the complete rewrite of its core code from C++ to Rust. This massive undertaking involved changing 1,155 files with over 110,000 line insertions and nearly 89,000 deletions. Despite the scale of this change, the Fish team has emphasized that there should be no direct impact on users - a remarkable achievement considering the comprehensive nature of the rewrite.

I find this quite impressive, that they rewrote the whole Fish core, but everything keeps working exactly in the same way (except very few minor things which change in only minor ways, which they list).

The rewritten codebase has grown from approximately 55,000 lines of C++ to 75,000 lines of Rust. According to community discussions, much of this increase can be attributed to Rust's formatting preferences, which tends to spread code across multiple lines, as well as the addition of new features. Some users have noted that the Rust version builds slightly slower and produces a larger binary - approximately 4.3 MB compared to the previous 2.4 MB for the C++ version.

Fish 4.0 vs 3.x Comparison

Feature Fish 4.0 Fish 3.x
Core language Rust C++
Code size ~75,000 lines ~55,000 lines
Binary size 4.3 MB 2.4 MB
Build time (release) ~37 seconds ~23 seconds
Dependencies Rust 1.70+, C compiler C++ compiler, C compiler
ncurses dependency No (requires terminfo) Yes

Notable Changes in Fish 4.0

  • New key notation system
  • Variables in command position that expand to subcommand keywords now forbidden
  • qmark-noglob feature enabled by default (? no longer acts as single-character glob)
  • XTerm's modifyOtherKeys keyboard encoding and kitty keyboard protocols now requested
  • Web configuration rewritten using Alpine.js

Why Users Love Fish

Fish has gained popularity primarily for its intuitive features that work well out of the box. Community discussions highlight that the shell's excellent autocompletion system is its most appreciated feature, requiring no manual configuration. Other praised aspects include its streamlined theme/prompt system and plugin management through oh-my-fish.

Many users mention that they continue using Fish for interactive shell usage while still writing scripts in Bash or POSIX shell for portability. This hybrid approach allows them to benefit from Fish's user-friendly features while maintaining compatibility with systems where Fish isn't installed.

Compatibility Considerations

A common point raised in discussions is the occasional friction when copying Bash commands into Fish due to syntax differences. Some users have developed creative workarounds, such as scripts that automatically route Bash commands through a persistent Bash instance when pasted into Fish.

The rewrite has also resulted in a few backwards-incompatible changes, including a new key notation system, changes to variable handling in command positions, and enabling the qmark-noglob feature by default (meaning ? no longer acts as a single-character glob). Additionally, Fish now requests XTerm's modifyOtherKeys keyboard encoding and kitty keyboard protocols' progressive enhancements.

For Distributors and Developers

The shift to Rust means significant changes in dependencies. Fish now requires Rust 1.70 or greater, while no longer needing a C++ compiler (though a C compiler is still required for some glue code and tests). CMake remains the recommended build system with version 3.5 as the minimum supported version.

Another notable change is that Fish no longer depends on the ncurses library, though it still uses a terminfo database. Packagers are advised to add a dependency on the package containing their terminfo database instead of curses.

The Web-based configuration has also been rewritten to use Alpine.js, representing another modernization effort alongside the core rewrite.

As Fish 4.0 rolls out across various package managers and platforms, it stands as an impressive example of how a major rewrite can be accomplished while maintaining the user experience that made the software popular in the first place. For users considering trying Fish or upgrading from previous versions, the transition should be remarkably smooth despite the substantial changes under the hood.

Reference: fish 4.0.0 (released February 27, 2025)