fish home | Main documentation page | Design document | Commands | FAQ | License

Design document


This is a description of the design principles that have been used to design fish. The fish design has three high level goals. These are:

  1. Everything that can be done in other shell languages should be possible to do in fish, though fish may rely on external commands in doing so.
  2. Fish should be user friendly, but not at the expense of expressiveness. Most tradeoffs between power and ease of use can be avoided with careful design.
  3. Whenever possible without breaking the above goals, fish should follow the Posix syntax.

To achive these high-level goals, the fish design relies on a number of more specific design principles. These are presented below, together with a rationale and a few examples for each.

The law of orthogonality

The shell language should have a small set of orthogonal features. Any situation where two features are related but not identical, one of them should be removed, and the other should be made powerful and general enough to handle all common use cases of either feature.


Related features make the language larger, which makes it harder to learn. It also increases the size of the sourcecode, making the program harder to maintain and update.


The law of minimalism

The shell should only contain features that cannot be implemented in a reasonable way outside of the shell. A large performance decrease, as well as some program complexity increase is acceptable in order to improve separation.


A modular project is easier to maintain since smaller programs are far easier to understand than larger ones. A modular project is also more future proof since the modules can be individually replaced. Modularity also decreases the severity of bugs, since there is good hope that a bug, even a serious one, in one module, does not take the whole system down.


The law of minimalism does not imply that a large feature set is bad. So long as a feature is not part of the shell itself, but a separate command or at least a shellscript function, bloat is fine.

Configurability is the root of all evil

Every configuration option in a program is a place where the program is too stupid to figure out for itself what the user really wants, and should be considered a failiure of both the program and the programmer who implemented it.


Different configuration options are a nightmare to maintain, since the number of potential bugs caused by specific configuration combinations quickly becomes an issue. Configuration options often imply assumptions about the code which change when reimplementing the code, causing issues with backwards compatibility. But mostly, configuration options should be avoided since they simply should not exist, as the program should be smart enough to do what is best, or at least a good enough approximation of it.


A special note on the evils of configurability is the long list of very useful features found in some shells, that are not turned on by default. Both zsh and bash support command specific completions, but no such completions are shipped with bash by default, and they are turned of by default in zsh. Other features that zsh support that are disabled by default include tab-completion of strings containing wildcards, a sane completion pager and a history file.

The law of user focus

When designing a program, one should first think about how to make a intuitive and powerful program. Implementation issues should only be considered once a user interface has been designed.


This design rule is different than the others, since it describes how one should go about designing new features, not what the features should be. The problem with focusing on what can be done, and what is easy to do, is that to much of the implementation is exposed. This means that the user must know a great deal about the underlying system to be able to guess how the shell works, it also means that the language will often be rather low-level.


The law of discoverability

A program should be designed to make its features as easy as possible to discover for the user.


A program whose features are discoverable turns a new user into an expert in a shorter span of time, since the user will become an expert on the program simply by using it.

The main benefit of a graphical program over a command line-based program is discoverability. In a graphical program, one can discover all the common features by simply looking at the user interface and guessing what the different buttons, menus and other widgets do. The traditional way to discover features in commandline programs is through manual pages. This requires both that the user starts to use a different program, and the she/he then remembers the new information until the next time she/he uses the same program.


Generated on Fri May 25 02:21:14 2012 for fish by  doxygen 1.5.9