Skip to main content

Command Palette

Search for a command to run...

From Zero to Productive: My Nushell Config

A practical configuration focused on speed, clarity, and comfort

Updated
14 min read
From Zero to Productive: My Nushell Config

Modern shells like zsh and fish have pushed the command line far beyond what traditional bash offers. With features like smart autocompletion, syntax highlighting, plugins, and rich prompts, they already feel like a big upgrade over classic text-based workflows. For many developers, switching from bash to fish or zsh is the first step toward a more productive terminal experience.

Nushell, however, takes a different—and more radical—approach. Instead of treating everything as plain text flowing through pipes, Nushell works with structured data. Commands output tables, records, and lists rather than raw strings, making it possible to filter, sort, and transform data in a way that feels closer to working with a programming language than a traditional shell. This model will feel familiar to anyone who has used PowerShell, which pioneered the idea of passing objects instead of text between commands.

Where Nushell stands apart is in how it applies this idea. PowerShell is deeply tied to the .NET ecosystem and primarily centered around Windows, with objects that map directly to .NET types. Nushell, on the other hand, is built from the ground up as a modern, cross-platform shell, designed to run consistently on Linux, macOS, and Windows. Its data model is shell-native rather than framework-bound, making it feel lighter, more predictable, and better suited to everyday CLI workflows.

In this post, I’ll walk through the configuration choices that took me from a fresh Nushell install to a genuinely productive setup: keybindings, prompts, defaults, and small tweaks that reduce friction and make Nushell feel like home—especially if you’re coming from zsh, fish, or even PowerShell.

Installation

Installing Nushell is straightforward on all major platforms, and the project provides first-class support for macOS, Windows, and Linux. You can choose between system package managers, prebuilt binaries, or building from source, depending on how much control you want.


macOS

On macOS, the recommended approach is using Homebrew:

brew install nushell

This installs Nushell system-wide and keeps it up to date with regular Homebrew upgrades. Once installed, you can start it by running:

nu

If you manage multiple shells, you can also add Nushell to your list of available login shells later, but it works perfectly well as a regular interactive shell without replacing your default one.


Windows

On Windows, Nushell integrates well with modern package managers.

Using winget (available by default on recent Windows versions):

winget install Nushell.Nushell

Alternatively, if you use Chocolatey:

choco install nushell

After installation, you can launch Nushell from Windows Terminal, which provides the best experience thanks to proper font rendering, colors, and Unicode support. Nushell runs natively on Windows and does not require WSL.


Linux

On Linux, Nushell is available in most major distributions’ package repositories.

Examples:

  • Arch Linux

      pacman -S nushell
    
  • Ubuntu / Debian

      apt install nushell
    
  • Fedora

      dnf install nushell
    

If your distribution ships an older version, you can always fall back to installing a prebuilt binary or building from source.


Cross-platform alternatives

If you want the same setup everywhere, Nushell also provides precompiled binaries for all platforms. You can download the appropriate archive, extract it, and place the nu binary somewhere in your PATH.

Another option is installing via Cargo:

cargo install nu

This works on all platforms supported by Rust and is useful if you already have a Rust toolchain installed.


Regardless of the platform, once nu is available in your PATH, the next step is the same everywhere: start Nushell, generate the initial configuration files, and begin customizing it to fit your workflow.

Configuration files

Nushell keeps its configuration split into two main files, each with a clear and well-defined role. Understanding how to edit them—and when to use each one—is key to building a clean and maintainable setup.

The first file is config.nu. This is where most of the user-facing behavior of Nushell is defined: keybindings, menus, prompt configuration, environment behavior, and general shell options. If something affects how Nushell feels while you’re using it, it probably belongs here. Changes to config.nu are applied the next time a Nushell session starts, making it the central place for shaping your interactive experience.

The second file is env.nu. This file is evaluated very early during shell startup and is specifically meant for environment variables. Anything that needs to exist before commands run—such as PATH modifications, EDITOR, locale settings, or tool-specific environment variables—should go here. Keeping environment-related logic in env.nu avoids subtle issues and makes your configuration easier to reason about.

To edit these files, Nushell provides built-in commands that respect your configured editor. Running config nu opens config.nu, and config env opens env.nu. This approach avoids hardcoding paths and works consistently across platforms. Once you save your changes and restart Nushell (or reload the configuration), the updates take effect.

By separating configuration and environment concerns into these two files—and using Nushell’s own commands to edit them—you get a setup that is not only powerful, but also clean, portable, and easy to evolve over time.

Initial configuration

When you first start using Nushell, the initial configuration is intentionally minimal, but two small changes make an immediate difference to the day-to-day experience.

The first step is setting a default editor. Many Nushell commands—such as editing configuration files, opening temporary buffers, or interacting with tools that expect an $EDITOR—rely on this value being defined. Explicitly configuring your editor ensures that Nushell integrates smoothly with the rest of your workflow, whether you prefer a terminal editor like Helix, Neovim, or Vim, or a graphical one. It’s a simple change, but it removes friction right away.

$env.config.buffer_editor = "nvim"

If Neovim is your editor of choice and you’d like a clear, practical introduction to it, I cover that in detail in my book.

The second step is disabling the startup banner. By default, Nushell displays a welcome message every time a new shell starts.

While helpful at first, it quickly becomes visual noise once you’re using Nushell regularly or opening many terminal sessions. Removing the banner results in a cleaner startup and a more focused terminal, especially when working inside tools like tmux or zellij.

$env.config.show_banner = false

These two adjustments don’t change how Nushell works, but they set the tone for the rest of the configuration: a shell that starts cleanly, respects your preferred tools, and stays out of your way unless you need it.

Prompt

This configuration defines a deliberately minimal prompt, with the goal of reducing visual noise and avoiding duplicated information.

By default, Nushell’s prompt includes contextual details such as the current working directory and, on the right side, timing information about the last command. While useful in some scenarios, this can become redundant in a modern terminal setup.


Minimal left prompt

$env.PROMPT_COMMAND = ""

PROMPT_COMMAND controls what Nushell renders as the main (left) prompt. Setting it to an empty string effectively removes all prompt content, leaving a clean, distraction-free command line.

The rationale here is that most modern terminal emulators—such as Alacritty or Windows Terminal—already display the current working directory in the window title or tab name. Repeating the same path information in the prompt adds no new value and consumes horizontal space, especially in deeply nested directories.

By removing it, the focus stays entirely on the command being typed.


Disabling the right prompt

$env.PROMPT_COMMAND_RIGHT = ""

The right prompt is commonly used to show execution time, timestamps, or status information for the last command. While this can be helpful when profiling performance or debugging slow commands, it is rarely useful during normal, day-to-day shell usage.

Unless you are actively measuring how long commands take to run, this timing information becomes background noise—something your eyes learn to ignore. Disabling the right prompt removes that unnecessary cognitive load and results in a calmer, more predictable terminal layout.

History

This history configuration is designed to make Nushell’s command history reliable, searchable, and safe across multiple sessions, while keeping performance predictable.

$env.config.history = {
  file_format: sqlite
  max_size: 5_000_000
  sync_on_enter: true
  isolation: true
}

Each option plays a specific role:


file_format: sqlite

Using SQLite instead of a plain text file gives Nushell a structured, indexed history store. This has several advantages:

  • Faster and more reliable history searches, even with large histories

  • Reduced risk of corruption compared to appending to a text file

  • Better handling of concurrent access when multiple shells are open

In practice, this makes history feel more like a database than a log file—something you can query efficiently rather than just scroll through.


max_size: 5_000_000

This sets a hard limit on the history database size (in bytes). Capping the size prevents unbounded growth over time, which can otherwise lead to slower searches and unnecessary disk usage.

A limit of around 5 MB is large enough to retain a long and useful command history, while still keeping performance snappy and storage under control. Old entries are automatically discarded when the limit is reached, so no manual cleanup is needed.


sync_on_enter: true

With this enabled, each command is written to history as soon as you press Enter, not when the shell exits. This is particularly useful if:

  • You run multiple Nushell instances in parallel

  • A shell crashes or is force-closed

  • You frequently open and close terminals

You don’t lose recent commands, and other running shells can immediately see the updated history.


isolation: true

History isolation ensures that each shell session maintains its own logical history context. Commands executed in one session do not instantly bleed into another, which avoids confusing or irrelevant suggestions when navigating history.

This is especially valuable when working on multiple projects at once or when using tools like tmux or zellij with many panes open. You get history that reflects what you were doing in that session, not noise from elsewhere.

Vi mode

Nushell supports both emacs and vi editing modes for the command line, but enabling vi mode can be significantly more ergonomic for long-term, keyboard-driven workflows.

$env.config.edit_mode = "vi"
$env.config.cursor_shape = {
  vi_insert: line
  vi_normal: block
}
$env.PROMPT_INDICATOR_VI_INSERT = "> "
$env.PROMPT_INDICATOR_VI_NORMAL = "$ "


Why vi mode is more ergonomic

The key ergonomic advantage of vi mode is that it allows you to navigate and edit text without moving your hands away from the home row—the default resting position of your fingers on the keyboard (ASDF / JKL;).

In emacs mode, navigating across words or jumping around a command often involves:

  • Modifier-heavy key combinations (Ctrl + …)

  • Or reaching for the arrow keys

Both actions break hand positioning and slow down editing. Vi mode, by contrast, uses single-key motions (w, b, e, 0, $, etc.) that keep your hands anchored on the home row, making movement faster and less fatiguing over time.


Clear separation between modes

Vi mode introduces a strict distinction between insert mode (typing text) and normal mode (navigating and editing). While this requires a small mental adjustment at first, it enables far more precise and efficient command-line editing once the muscle memory is built.

To make this distinction obvious, the configuration uses visual cues.


Cursor shape as a mode indicator

$env.config.cursor_shape = {
  vi_insert: line
  vi_normal: block
}

Changing the cursor shape provides immediate, subconscious feedback about the current mode:

  • Line cursor → insert mode (typing text)

  • Block cursor → normal mode (navigation and editing)

This mirrors the behavior of modal editors like Vim and Helix and helps prevent accidental typing in the wrong mode.


Prompt indicators for extra clarity

$env.PROMPT_INDICATOR_VI_INSERT = "> "
$env.PROMPT_INDICATOR_VI_NORMAL = "$ "

The prompt itself also changes depending on the active mode. This reinforces the cursor shape signal and makes the current state unmistakable, even in terminals where cursor shape changes might not be obvious or supported.

Keybindings

History Hint Complete with Ctrl + Space

$env.config.keybindings ++= [
  {
     name: history_hint_complete
     modifier: control
     keycode: space
     mode: vi_insert
     event: [
       { send: HistoryHintComplete }
    ]
  }
 ]

Nushell’s history suggestions are one of its most powerful features, and this keybinding improves the overall efficiency of using that feature:

  • Ergonomically better than default keybindings: By binding the history completion feature to Ctrl + Space, you avoid the need to reach for the arrow keys, which interrupts your typing flow and slows down interaction. Instead, you can use Ctrl + Space as a much more comfortable alternative, keeping your hands anchored on the home row.

    In vi mode, you typically don’t need to move your hands away from the home row for basic operations like navigating the command history, and this keybinding is consistent with that design. Arrow keys require awkward finger stretches, especially when you’re typing fast or working in a split terminal.

  • Optimized for frequent use: Since history completion in Nushell is a feature you will use often, being able to trigger it with a single keystroke (Ctrl + Space) is a huge time-saver. It’s faster and feels more natural than reaching for the up or down arrow keys, particularly when navigating through long histories.

    This feature is particularly important in Nushell because its suggestions aren’t just about previous commands, but also about contextual hints—making it more likely you will use the history completion multiple times during your workflow.

System Trash

Nushell provides a convenient way to handle deleted files through a system trash configuration, which can make file deletion safer and more forgiving.

$env.config.rm.always_trash = true

How it works

By default, many shells (including basic rm in bash) permanently delete files, which can be risky—especially if you accidentally remove something important. With this configuration:

  • always_trash = true tells Nushell that whenever you use the rm command, files should be sent to the system trash/recycle bin instead of being deleted immediately.

  • The exact behavior depends on the operating system:

    • macOS → Files go to the Trash.

    • Windows → Files go to the Recycle Bin.

    • Linux → Files go to the user’s trash directory (e.g., ~/.local/share/Trash), following the FreeDesktop.org specification.

This means you can safely undo deletions, restore files, or review them before permanently removing them.

True color

Enabling true color in Nushell is a small but important configuration, especially when working remotely on a server using a text-mode editor like Helix or Neovim.

# enable true color
$env.COLORTERM = "truecolor"

What it does

  • COLORTERM is an environment variable that tells applications the terminal supports 24-bit color, also known as true color.

  • Setting it to "truecolor" ensures that both the shell and terminal-based applications can use the full RGB color range, rather than being limited to 16 or 256 colors.


Why it’s important for remote editing

  1. Consistent color rendering
    When you SSH into a server, the terminal may not automatically detect true color support. Without this variable, editors like Helix or Neovim might fall back to limited color schemes, making syntax highlighting less informative or harder to read.

  2. Better syntax highlighting
    True color allows modern editors to use rich themes accurately, so things like code highlighting, git diff colors, or syntax error markers appear exactly as intended.

  3. Improved terminal experience
    Even outside the editor, Nushell itself can render colored outputs (like tables, errors, or commands) with full fidelity, which is particularly useful for scripts, logs, or pipelines with multiple colors.

  4. Cross-terminal consistency
    By explicitly setting COLORTERM=truecolor, you ensure that the color behavior is consistent whether you’re on Alacritty, Windows Terminal, iTerm2, or a remote SSH session. This avoids surprises when moving between local and remote environments.

Summary

With these configurations in place, Nushell transforms from a minimal, out-of-the-box shell into a powerful, ergonomic, and modern command-line environment. We’ve set up a minimal, distraction-free prompt, enabled vi-mode with clear visual cues, optimized keybindings for efficiency, configured a reliable and fast history system, ensured safe file deletion with system trash, and enabled true color for a rich, consistent visual experience—even on remote servers. Each tweak focuses on reducing friction, improving productivity, and letting the shell work for you rather than demanding constant attention. The result is a Nushell setup that is not only functional and safe, but also comfortable and enjoyable to use day after day, whether you’re navigating files, writing scripts, or managing multiple projects across platforms.

# minimal prompt
$env.PROMPT_COMMAND = ""

# disable right prompt
$env.PROMPT_COMMAND_RIGHT = ""

# setup default editor
$env.config.buffer_editor = "nvim"

# disable banner
$env.config.show_banner = false

# enable system trash
$env.config.rm.always_trash = true

# setup history
$env.config.history = {
  file_format: sqlite
  max_size: 5_000_000
  sync_on_enter: true
  isolation: true
}

# enable vi mode
$env.config.edit_mode = "vi"
$env.config.cursor_shape = {
  vi_insert: line
  vi_normal: block
}
$env.PROMPT_INDICATOR_VI_INSERT = "> "
$env.PROMPT_INDICATOR_VI_NORMAL = "$ "

# key bindings
$env.config.keybindings ++= [
  {
     name: history_hint_complete
     modifier: control
     keycode: space
     mode: vi_insert
     event: [
       { send: HistoryHintComplete }
    ]
  }
 ]

# enable true color
$env.COLORTERM = "truecolor"

However, Nushell stands out as a highly configurable shell, allowing you to tailor almost every aspect of its behavior, appearance, and interaction to your workflow. From prompts and keybindings to history, editor integration, and system behavior, almost every part of the shell can be adjusted to suit your preferences.

If you want to explore all the available configuration options, Nushell provides a built-in documentation command:

config nu --doc | nu-highlight

Thank you for taking the time to read this post all the way through! I hope you found the tips and configurations useful for making Nushell a more productive and enjoyable shell. Be sure to come back for future posts, where I’ll share more insights, tricks, and practical setups to help you get even more out of your command-line workflow.