Nushell 0.83

Nushell, or Nu for short, is a new shell that takes a modern, structured approach to your command line. It works seamlessly with the data from your filesystem, operating system, and a growing number of file formats to make it easy to build powerful command line pipelines.

Today, we're releasing version 0.83 of Nu. This release adds match guards, stronger type checking features, unit testing improvements, flexible variable initializations, and more.

Where to get it

Nu 0.83 is available as pre-built binariesopen in new window or from crates.ioopen in new window. If you have Rust installed you can install it using cargo install nu.

NOTE: The optional dataframe functionality is available by cargo install nu --features=dataframe.

As part of this release, we also publish a set of optional plugins you can install and use with Nu. To install, use cargo install nu_plugin_<plugin name>.

Themes of this release / New features

Fixes, stabilization and shoutouts

@WindSoilderopen in new window9747open in new windowRedirection: make o>, e>, o+e>'s target support variables and string interpolation
@kubouchopen in new window9679open in new windowFix broken constants in scopes
@rusty-julesopen in new window9594open in new windowFix: return all headers with the same name from http <method>
@baehyunsolopen in new window9582open in new windowmake the behaviours of last and first more consistent
@hanjunghyukopen in new window9623open in new windowFix explore crashes on {}
@YassineHaouzaneopen in new window9616open in new windowFix: update engine_state when history.isolation is true (#9268)
@IanManskeopen in new window9603open in new windowFix headers command handling of missing values
@AyushSingh13open in new window9580open in new windowfixes which showing aliases as built-in nushell commands
@mengsuenyanopen in new window9662open in new windowfix the command cp -u src dst/mv -u src dst doesn't work when the…

Changes to commands

Since last release, some commands have changed and some have been created, here is a list of some changes and what they mean:

Command set refinement efforts

Again with this new release, we are continuing refining our set of core commands. As part of this, another set of commands have moved to extra. Thanks to folks who are helping our efforts on the road to 1.0!

Note No command has been removed completely, they have just been moved in the extra feature of Nushell. simply use cargo ... --features extra to reenable them.

Math commands have been moved by @stormasmopen in new window in #9674open in new window, #9657open in new window and #9647open in new window and the following commands have been moved in #9404open in new window: fmt, each while, roll, roll down, roll left, roll right, roll up, rotate, update cells, decode hex, encode hex, from url, to html, ansi gradient, ansi linkand format

Language improvements

Since last release, a few changes have happened to the Nu language itself.

Declaration and assignment of variables

Until now, declaration keywords such as let and mut have required the use of parentheses around pipelines to assign the output of a chain of command to a variable. Thanks to @sophiajtopen in new window in #9658open in new window and #9589open in new window, this syntax has been relaxed for let and mut. Let's give some examples!

let filenames = ls | where type == file | get name


mut my_var = "hello world" | str length

are now completely valid Nushell code.

Note this new syntax does not work on const and it does not apply to assignment of values to variables, e.g.

$env.FILENAMES = ls | where type == file | get name

is not parsed as valid Nushell.

Another parser improvement has to do with the use of if and match in variable assignment. In #9650open in new window, @Windsoilderopen in new window made the following Nushell snippets possible:

mut a = 3
$a = if 4 == 3 { 10 } else {20}


$env.BUILD_EXT = match 3 { 1 => { 'yes!' }, _ => { 'no!' } }

Input / output type checking and annotations (@sophiajtopen in new window)

Nushell as a language is more strictly typed than other shell languages. However, not everything was type-checked nor possible to annotate and this new release tries to fill this gap a bit more.

Note in the following of this section, the term input / output signature is used. This describes the input of a command and the associated output type of the command for the given input type, e.g. in ls | get the input type of get is a table and its output type is a string, so we can say that the input / output signature of get here is table -> string.

Please note that input / output signatures always come in pair.

First, #9686open in new window makes the input / output type signatures clearer in the help pages of commands. Then, #9690open in new window and #9680open in new window enable input / output type annotations on custom commands and enforce a strong type checking on the input and output of commands. This means a few things

  • the input / output of custom commands can be annotated
def sum []: list<int> -> int {
    math sum
  • some type-invalid calls to commands are now parsed as an error, e.g. 123 | get foo gives the following error
Error: nu::parser::input_type_mismatch

  × Command does not support int input.
   ╭─[entry #2:1:1]
 1 123 | get foo
   ·       ─┬─
   ·        ╰── command doesn't support int input

This is still a work in progress, so some commands might have incorrect or missing input / output type annotations 😮 This is expected and we worked and are working on this to fix all incorrect signatures (#9755open in new window, #9749open in new window, #9707open in new window, #9706open in new window, #9695open in new window, #9683open in new window, #9775open in new window, #9741open in new window, #9742open in new window, #9739open in new window and #9778open in new window)!


In between the two releases, @1Kinotiopen in new window has worked on some nice improvements to the language

Configuration tweaks

Contributions have been made to give a more consistent and sensible default experience in Nushell, both when using the config file or when not having a config, e.g. with nu -n. A better right prompt has been written in #9585open in new window and #9581open in new window and the default configuration has been polished in #9676open in new window.

The standard library

The biggest topic in this 0.83 release for the standard library has been the test runner!

Thanks to @Yethalopen in new window, the test runner of the standard library can now use annotations to decide whether or not to run a command as part of the test suite of a project: #9628open in new window, #9622open in new window, #9611open in new window and #9406open in new window.

For instance, we can now write a module as follows

def add [a: int, b: int] {
    $a + $b

def addition [] {
    use std assert
    assert equal (add 1 2) 3

and std testing run-tests would successfully run the addition test, no need to define tests with test_ in their names!

Thanks to @Hofer-Julianopen in new window (#9607open in new window), the standard library now also comes with a pwd command that tells you were you are in the filesystem.

Breaking changes

PLEASE NOTE: there are some big breaking changes in this release. These include:

  • Removal of let-env (now use the $env.FOO = "BAR" form instead)
  • Stricter checking of input/output types
  • Transitioning of a set of commands to now be available via extra feature rather than default

Full list of breaking changes:

Full changelog