A modern shell that treats everything as structured data instead of raw text. Pipelines work with tables, records, and lists — not just strings. Think of it as a shell that understands JSON, CSV, TOML, and YAML natively.
| Platform | Command |
|---|
| macOS (Homebrew) | brew install nushell |
| Windows (Winget) | winget install nushell |
| Windows (Chocolatey) | choco install nushell |
| Windows (Scoop) | scoop install nu |
| Ubuntu/Debian | sudo apt install nushell (or download from GitHub releases) |
| Arch Linux | sudo pacman -S nushell |
| Fedora/RHEL | sudo dnf install nushell |
| Cargo (All platforms) | cargo install nu |
| Nix | nix-env -iA nixpkgs.nushell |
Launch: Run nu from any shell to start Nushell. Set as default shell: chsh -s $(which nu)
Nushell pipelines pass structured data (tables, records, lists), not text:
# Traditional shell: text → grep → awk → text
# Nushell: table → where → select → table
ls | where size > 1mb | sort-by size --reverse | first 5
Data types: strings, integers, floats, booleans, dates, durations, file sizes, lists, records, tables
| Command | Description |
|---|
ls | List directory as a structured table |
ls -la | List all files (including hidden) in long format |
cd path/to/dir | Change directory |
cp source dest | Copy files or directories |
mv source dest | Move or rename files |
rm file | Remove files |
mkdir dirname | Create directory |
open file.json | Open file as structured data (auto-detects format) |
open file.csv | Open CSV as a table |
open file.toml | Open TOML as a record |
save output.json | Save pipeline output to file |
cat file.txt | Display file contents as text |
ps | Show running processes as a table |
sys | Show system information |
which command | Find command location |
help commands | List all available commands |
help <command> | Show help for a specific command |
| Command | Description |
|---|
ls | where size > 10mb | Filter files larger than 10 MB |
ls | where name =~ "\.rs$" | Filter by regex on filename |
ls | where type == "dir" | Show only directories |
ls | where modified > 2day | Files modified in last 2 days |
ls | select name size | Show only name and size columns |
ls | reject type | Remove the type column |
ls | get name | Extract just the name column as a list |
ls | first 5 | Show first 5 entries |
ls | last 3 | Show last 3 entries |
ls | skip 10 | Skip first 10 entries |
ls | nth 0 2 4 | Select entries by index |
ls | length | Count number of entries |
ls | uniq | Remove duplicate entries |
| Command | Description |
|---|
ls | sort-by size | Sort by size ascending |
ls | sort-by size --reverse | Sort by size descending |
ls | sort-by name | Sort alphabetically |
ls | group-by type | Group entries by type |
ls | group-by {get name | path parse | get extension} | Group by file extension |
| Command | Description |
|---|
"hello world" | str upcase | Convert to uppercase |
"HELLO" | str downcase | Convert to lowercase |
" hello " | str trim | Trim whitespace |
"hello" | str contains "ell" | Check if string contains substring |
"hello" | str replace "l" "L" | Replace characters |
"hello world" | split row " " | Split string into list |
["hello" "world"] | str join ", " | Join list into string |
"hello" | str length | Get string length |
"hello" | str starts-with "he" | Check string prefix |
| Command | Description |
|---|
open data.json | get field_name | Access a field in JSON |
open data.json | get nested.field | Access nested fields |
{name: "Alice", age: 30} | Create a record |
[1 2 3 4 5] | Create a list |
[[name age]; [Alice 30] [Bob 25]] | Create a table |
$data | to json | Convert to JSON |
$data | to csv | Convert to CSV |
$data | to toml | Convert to TOML |
$data | to yaml | Convert to YAML |
$data | to md | Convert to Markdown table |
| Command | Description |
|---|
[1 2 3 4] | math sum | Sum of values |
[1 2 3 4] | math avg | Average of values |
[1 2 3 4] | math max | Maximum value |
[1 2 3 4] | math min | Minimum value |
[1 2 3 4] | math median | Median value |
ls | get size | math sum | Total size of listed files |
1 + 2 | Basic arithmetic |
10 / 3 | Division |
2 ** 8 | Exponentiation |
| Command | Description |
|---|
http get https://api.example.com/data | Fetch URL and parse response |
http post https://api.example.com/data {key: "value"} | POST request with body |
fetch url | get field | Fetch and extract specific field |
# Variables (immutable by default)
let name = "Alice"
let count = 42
let files = (ls | where size > 1mb)
# Mutable variables
mut counter = 0
$counter += 1
# If/else
if $count > 10 { "big" } else { "small" }
# Loops
for file in (ls) { print $file.name }
ls | each { |row| $row.name | str upcase }
# Custom commands (functions)
def greet [name: string] { $"Hello, ($name)!" }
greet "World"
| File | Purpose |
|---|
$nu.config-path | Main configuration (config.nu) |
$nu.env-path | Environment configuration (env.nu) |
# Show config file location
$nu.config-path
# Edit config
config nu # Open config.nu in editor
config env # Open env.nu in editor
# In config.nu
$env.config = {
show_banner: false # Disable welcome banner
table: {
mode: rounded # Table style: rounded, compact, thin, none
}
completions: {
algorithm: "fuzzy" # Fuzzy tab completion
}
history: {
max_size: 10000 # History entries to keep
file_format: "sqlite" # sqlite or plaintext
}
}
# Find largest files in a project
ls **/* | where type == "file" | sort-by size --reverse | first 20
# Parse and query JSON API
http get https://api.github.com/repos/nushell/nushell | select stargazers_count forks_count
# Convert between formats
open data.csv | to json | save data.json
# Analyze log files
open access.log | lines | parse "{ip} - - [{date}] \"{method} {path} {proto}\" {status} {size}"
| where status == "404" | group-by path | sort-by -r
# Quick system overview
sys | get host
ps | sort-by cpu --reverse | first 10
| Feature | Bash/Zsh | Nushell |
|---|
| Data model | Text streams | Structured tables |
| Parsing output | grep, awk, sed | Built-in where, select, get |
| JSON handling | Requires jq | Native (open file.json) |
| Error handling | Exit codes | Rich error messages |
| Tab completion | Basic | Context-aware |
| Type system | None | Integers, strings, dates, sizes, etc. |
| Learning curve | Familiar | New syntax to learn |
| External commands | Native | Fully supported |