fish-shell: what the Rust rewrite changes for people who install it
The user-friendly command line shell.
At a glance
- What is it?
- fish is a shell that ships syntax highlighting, autosuggestions and tab completions with no configuration. The repository is now Rust, built through CMake, and the install path matters more than the language does.
- Who is it for?
- Adopt fish if you want syntax highlighting, autosuggestions and completions without writing a config file, and if you are willing to keep a POSIX shell around for scripts. Do not adopt it as the interpreter for portable scripts or as a drop-in for bash startup files.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem fish solves is configuration debt, not scripting
Most interactive shells are blank at first launch. You add a prompt, a completion system, a history search binding, and a syntax highlighter, and each of those is a separate plugin with its own update cycle. fish inverts that: the README states it includes syntax highlighting, autosuggest-as-you-type and tab completions that work with no configuration required. The target user is someone who lives in a terminal all day and does not want to maintain a plugin manager to get a usable prompt and completions. It is not aimed at people writing portable shell scripts. fish's own documentation points readers to a tutorial and tells them to search for the phrase "unlike other shells", which is a candid admission that the language diverges from POSIX. That divergence is the point. A shell that behaves like bash but looks nicer would still leave you maintaining the same plugin stack.
What the repository tells you about the mechanism
The primary language field now reads Rust, and the build instructions confirm it: compiling fish requires Rust 1.85 or later plus cargo, CMake 3.15 or later, and a C compiler that is used for system feature detection and a test helper binary. So the architecture is a Rust core with a small C component retained for platform probing, not a clean single-language rewrite. PCRE2 is optional and, per the README, will be downloaded if missing, and gettext's msgfmt tool is optional for translation support. An Internet connection is listed as a build requirement because other dependencies are fetched automatically. That last detail matters more than it looks: a build is not hermetic by default, and an offline or air-gapped machine will need the dependency question answered before anyone runs cmake. The runtime side is lighter. Running fish needs common Unix utilities, with mktemp called out explicitly alongside the basic POSIX set, and the README says the full coreutils plus find and awk is preferred.
Installing fish: the commands the README actually gives
On macOS the documented routes are brew install fish, sudo port install fish, an installer from fishshell.com, or a standalone app. The README notes the minimum supported macOS version is 10.12. On Ubuntu the README gives a four-line sequence: sudo apt-add-repository ppa:fish-shell/release-4, sudo apt update, sudo apt install fish. Debian, Fedora, openSUSE and RHEL/CentOS packages come from the openSUSE Build Service. Windows users are directed to WSL with the Linux instructions, or to Cygwin and MSYS2. Once installed, the README's instruction is simply to run fish from your current shell to try it out. Building from source uses CMake: mkdir build; cd build, then cmake .., cmake --build ., and sudo cmake --install . The README itself warns that this route makes fish difficult to uninstall or upgrade, and points to packaged builds instead. A Cargo path also exists, with the README's example using uv to install Sphinx for man pages and --help output.
The CMake options that decide how your build behaves
These are the keys worth knowing before you compile. Rust_COMPILER and Rust_CARGO set the paths to rustc and cargo; if unset, CMake checks $PATH and ~/.cargo/bin. Rust_CARGO_TARGET passes a target to cargo and is what you set for cross-compilation. WITH_DOCS=ON|OFF controls documentation and defaults to ON when Sphinx is installed. FISH_USE_SYSTEM_PCRE2=ON|OFF picks between an installed PCRE2 and the downloaded one, normally autodetected. WITH_MESSAGE_LOCALIZATION=ON|OFF decides whether translations are included. extra_functionsdir, extra_completionsdir and extra_confdir compile in additional directories searched for functions, completions and configuration snippets, which is the supported way to bake site-specific definitions into a build. For cross-compilation there is FISH_INDENT_FOR_BUILDING_DOCS, which points at a fish_indent executable usable on the compile host; the README suggests cargo build --bin fish_indent and setting the variable to $PWD/target/debug/fish_indent. That option exists because building HTML docs requires running fish_indent, and a cross-compiled binary will not run on the build machine.
Optional features that quietly become hard dependencies
fish runs without most of these, but the experience degrades in ways that are easy to misdiagnose. Builtins with a --help option or usage messages need man to display anything. Automated completion generation from manual pages needs Python 3.5 or later. The fish_config web configuration tool also needs Python 3.5 or later plus a browser. The alt-o binding needs the file program. Clipboard integration on the default Ctrl-V and Ctrl-X bindings needs one of xsel, xclip, wl-copy/wl-paste or pbcopy/pbpaste. Full completions for yarn and npm require the all-the-package-names NPM module. On platforms without color support in ls, such as OpenBSD, colorls is used if installed. None of this blocks installation, and that is exactly the problem: a minimal container image will install fish successfully and then fail to paste, fail to open help, and fail to complete npm subcommands, with no single error pointing at the cause.
Where fish is the wrong tool
fish is not a POSIX shell, and the README does not pretend otherwise. Scripts written for sh, bash or zsh will not run under it, and the project's own framing directs new users to a tutorial section labelled "unlike other shells". If your build images, CI steps or deployment scripts assume /bin/sh semantics, fish cannot replace that interpreter. The second limitation is the build path. The README states plainly that building from source makes fish difficult to uninstall or upgrade, and recommends packaged builds instead, which is unusual guidance for a project to publish about its own instructions. Treat that as a signal: the intended consumption route is a package manager, and the CMake workflow exists for platforms without packages and for people building development versions. Third, the automatic dependency download means a source build is not reproducible without pre-seeding PCRE2 and controlling network access. Fourth, the repository metadata reports the licence as NOASSERTION. If you are packaging fish for redistribution, read the licence file in the repository rather than relying on the metadata field.
bash and zsh: a different answer to the same question
The real alternative is not another shell binary, it is the plugin approach. zsh plus a framework such as oh-my-zsh or a hand-written .zshrc gives you syntax highlighting, autosuggestions and completions too, and it does so while remaining a POSIX-compatible shell that can run your existing scripts. The difference in approach is where the behaviour lives. In zsh the features are external code you install and update; in fish they are compiled into the binary, which is why the README can claim they work with no configuration. That trade has two sides. You stop maintaining plugin versions, and you also stop being able to swap out the completion engine or the highlighter for a different implementation. bash is the other end of the spectrum: universally present, no install step at all on most systems, and no highlighting or autosuggestion unless you add readline configuration that most people never write. If your constraint is that the shell must already exist on every machine you touch, bash wins by default. If your constraint is that the interactive experience must be good without you curating it, fish is the one that ships that in the binary.
Upgrade cost and what to check before you commit
The release cadence visible in the repository is fast: 4.9.1, 4.9.2 and 4.9.3 all landed within September 2026, days apart. For a shell that most people install once and forget, that is a lot of patch releases to track, and it suggests either active bug fixing or a stabilization period after a larger change. Either way, the practical implication is that pinning matters. If you build from source, pin a tag rather than tracking master, because the README's Cargo example explicitly notes you can check out a specific version instead of the latest development version. If you install from a distribution, check which release you are getting; the README's Ubuntu instructions point at a PPA named release-4, which is a stronger guarantee of currency than a distribution's default archive. On the licence side, the metadata says NOASSERTION, so anyone redistributing fish inside a product image should read the repository's licence file directly. That is a packaging question, not a legal opinion, and it is the one item on this list that cannot be answered from the README.
Editorial conclusion
Adopt fish if you want syntax highlighting, autosuggestions and completions without writing a config file, and if you are willing to keep a POSIX shell around for scripts. Do not adopt it as the interpreter for portable scripts or as a drop-in for bash startup files. Before committing, verify three things on your own machine: that the package you install is release 4.x rather than a distribution's older build, that your target platform has the utilities the README lists (mktemp plus coreutils, find and awk), and that fish's own licence file matches what your legal review requires, because the repository metadata reports NOASSERTION rather than a named licence.
Community notes