In our TechRadar Spring 2025 edition we highlighted the IntelliJ HTTP client and Bruno as alternatives to Postman, and also introduced you to Nushell. This post will focus on the latter.

The goal of Nushell is to take the Unix philosophy of shells, where pipes connect simple commands together, and combine it with a rich programming language. Nushell connects both by bringing a rich programming language and a full-featured shell together into one package, that runs on Linux, macOS, and Windows. Nushell uses structured data everywhere, for example output of ls command, or REST API calls.

If you work with REST APIs, you probably know the ritual of quickly testing your newly created endpoint: Fire-up your favourite HTTP client, or opening up a Shell. After you have properly constructed your HTTP request, you run your curl command in some standard terminal, get back a chunk of JSON, and then need to use tools like jq, grep, or awk to make something useful out of it. It works, has nice output, but the command itself oftenly seems complex and hard to read.

Nushell offers a different approach. Instead of treating everything as text, Nushell treats data as structured information. The output of an ls command? A table. The response from a REST API? Also a table. And that makes a world of difference. In this post, I’ll dive into some practical examples of Nushell using a local REST API. We’ll use the well-known Petstore API to show how Nushell makes working with JSON responses simpler and more intuitive.

Installation

You can install Nushell through various package managers. For macOS:

brew install nushell

For Linux and other platforms, see the installation instructions at https://www.nushell.sh/book/installation.html.

Start Nushell with:

nu

The Setup: Petstore API

For these examples, we’ll use a local instance of my Swagger Petstore API running on localhost:8080. My API has a /v2/pets endpoint that returns a list of pets in JSON format. It already has 5 pets in the store.

From JSON to Table: The Basic Pattern

Let’s start with the simplest example. In a traditional shell, you would do this:

curl -s http://localhost:8080/v2/pets

This gives you raw JSON:

[
  { "name": "Luna", "tag": "friendly", "id": 1 },
  { "name": "Charlie", "tag": null, "id": 2 },
  ...
]

In Nushell, you simply add | from json:

curl -s http://localhost:8080/v2/pets | from json

And you immediately get a neat table:

╭───┬─────────┬──────────┬────╮
│ # │  name   │   tag    │ id │
├───┼─────────┼──────────┼────┤
│ 0 │ Luna    │ friendly │  1 │
│ 1 │ Charlie │          │  2 │
│ 2 │ Milo    │ playful  │  3 │
│ 3 │ Bella   │ friendly │  4 │
│ 4 │ Max     │          │  5 │
╰───┴─────────┴──────────┴────╯

That from json command is the only extra thing you need. Nushell parses the JSON and presents it as a table. No jq, no complex selectors, just readable data.

Filtering and Sorting

Now it gets interesting. Because your data is now structured, you can easily work with it using Nushell’s built-in commands.

Sorting by name

curl -s http://localhost:8080/v2/pets | from json | sort-by name
╭───┬─────────┬──────────┬────╮
│ # │  name   │   tag    │ id │
├───┼─────────┼──────────┼────┤
│ 0 │ Bella   │ friendly │  4 │
│ 1 │ Charlie │          │  2 │
│ 2 │ Luna    │ friendly │  1 │
│ 3 │ Max     │          │  5 │
│ 4 │ Milo    │ playful  │  3 │
╰───┴─────────┴──────────┴────╯

Show only friendly pets

curl -s http://localhost:8080/v2/pets | from json | where tag == "friendly"
╭───┬───────┬──────────┬────╮
│ # │ name  │   tag    │ id │
├───┼───────┼──────────┼────┤
│ 0 │ Luna  │ friendly │  1 │
│ 1 │ Bella │ friendly │  4 │
╰───┴───────┴──────────┴────╯

Select only the names

curl -s http://localhost:8080/v2/pets | from json | select name
╭───┬─────────╮
│ # │  name   │
├───┼─────────┤
│ 0 │ Luna    │
│ 1 │ Charlie │
│ 2 │ Milo    │
│ 3 │ Bella   │
│ 4 │ Max     │
╰───┴─────────╯

Combining operations

The beauty is that you can combine these operations, just like you’re used to with Unix pipes:

curl -s http://localhost:8080/v2/pets
  | from json
  | where tag != null
  | sort-by name
  | select id name tag
╭───┬────┬───────┬──────────╮
│ # │ id │ name  │   tag    │
├───┼────┼───────┼──────────┤
│ 0 │  4 │ Bella │ friendly │
│ 1 │  1 │ Luna  │ friendly │
│ 2 │  3 │ Milo  │ playful  │
╰───┴────┴───────┴──────────╯

This fetches all pets, filters out items without a tag, sorts by name, and shows only the relevant columns. Each step in the pipe works with structured data, not text lines.

Query Parameters

The Petstore API supports query parameters. You can simply include them in the URL:

curl -s "http://localhost:8080/v2/pets?tags=friendly&tags=playful&limit=2" | from json
╭───┬───────┬──────────┬────╮
│ # │ name  │   tag    │ id │
├───┼───────┼──────────┼────┤
│ 0 │ Luna  │ friendly │  1 │
│ 1 │ Milo  │ playful  │  3 │
╰───┴───────┴──────────┴────╯

Data Aggregation

Nushell also has powerful commands for data analysis. Let’s say you want to know how many pets there are per tag:

curl -s http://localhost:8080/v2/pets
  | from json
  | group-by tag
  | transpose tag count
  | update count { |row| $row.count | length }
╭───┬──────────┬───────╮
│ # │   tag    │ count │
├───┼──────────┼───────┤
│ 0 │ friendly │     2 │
│ 1 │ playful  │     1 │
╰───┴──────────┴───────╯

This groups the pets by tag, transposes the data so tags appear as rows, and counts how many items are in each group.

POST Requests

Nushell works just fine with other HTTP methods too. Adding a new pet:

curl -s -X POST http://localhost:8080/v2/pets -H "Content-Type: application/json" -d '{"name": "Fluffy", "tag": "sleepy"}'
  | from json
╭──────┬────────╮
│ name │ Fluffy │
│ tag  │ sleepy │
│ id   │ 6      │
╰──────┴────────╯

The response is again displayed nicely as a table, including the generated ID.

Why This Is Useful

Compare this Nushell command:

curl -s http://localhost:8080/v2/pets | from json | where tag == friendly | select name

With the jq equivalent:

curl -s http://localhost:8080/v2/pets | jq '[.[] | select(.tag == "friendly") | {name: .name}]'

Both work, but the Nushell version reads more like natural language.

If you’re used to jq, there are still some advantages when using nushell:

  • Consistency: The same commands (where, select, sort-by) work for all structured data, not just JSON

  • Readability: where tag == "friendly" is more intuitive than jq '[.[] | select(.tag == "friendly")]

  • No context switching: You stay in your shell, no need to learn new tool-specific syntax

  • Type awareness: Nushell understands data types (integers, strings, etc.) and behaves accordingly

Further Experimentation

Besides what I have shown in this blogpost, Nushell can do much more. You can check out the following features:

  • to csv and to json: convert between formats

  • save: write output directly to a file

  • http get: Nushell’s built-in HTTP client (no curl needed)

  • Custom commands: write your own reusable functions

For example, with Nushell’s http command it becomes even more compact:

http get http://localhost:8080/v2/pets | where tag == "dog"

The from json step isn’t even needed - Nushell automatically detects that it’s JSON.

Conclusion

Nushell has been around for a couple of years, but it is still in the 0.x release stage (version 0.108.0 at the time of writing). Therefore, it is very interesting to play around with it for local experiments and scripts, and see what the advantages and disadvantages are compared to other shells and tools.

The core idea - data as a first-class citizen instead of text - makes working with modern APIs and structured data much more natural. If you regularly work with JSON APIs, Nushell is definitely worth trying out.

Start Nushell, try out the examples, and discover how it can improve your workflow. The learning curve is low if you’re already familiar with Unix shells, and the benefits become clear quickly. Also take a look to Hubert’s posts on Nushell Niceties to learn even more!

shadow-left