Summary: I've written a small nu-shiki script for generating nice images of Nushell commands with their outputs. It can also be used to render images of code in any language supported by Shiki. It's useful when sharing images of code is the best available option.
For the longest time, Linux shell scripting felt annoying to me. I was able to use Bash, Zsh and Fish to achieve my goals, but they always left me with a bad feeling. Since I'm quite enthusiastic about functional programming, I was more than happy when a colleague told me about Nushell back in January 2024. I played around with it the same day, and have been using it daily since then.
Personally, Nushell feels like the perfect mixture:
The case for Nushell goes more in-depth and is worth reading.
In February 2024, about a month after first discovering Nushell, more people in my team at work got excited and started to develop tooling in Nushell. At this point, we had ~3 000 lines of tools written in Bash. By the end of the year, in just 10 months, we had rewritten all tooling in Nushell and the new versions worked really well. (This is the topic for a separate post.)
There's a fairly frequent need within the team to share Nushell commands and outputs. Nushell renders structured data really nicely. Following is an example of a random table (essentially a list containing records, which usually share some structure).
The company uses Slack for internal communication, and that is where most commands and outputs are being shared. This is how that same table looks like when shared as a code block.
No syntax highlighting, but otherwise passable. But check what happens when the width is constrained, like in sidebar threads.
Snippets help a bit, since you can download them, but they still render poorly in sidebars.
Since I run Slack in the browser, I added some custom CSS to improve the situation a bit.
At least code blocks are readable now, but with a scrollbar in sidebar threads.
The team largely resorted to screenshots. Usually, there isn't a need to copy the command or the output (you're just trying to convey some information), so the lack of text isn't that problematic. But screenshots would always end up looking a bit messy, which was sometimes distracting.
Personally, I wanted something better fit for the purpose, so I started developing nu-shiki. The idea is fairly simple: instead of taking a screenshot of the terminal, render a command and it's output with ANSI escape codes. Then let Shiki generate matching HTML, and take a screenshot of it.
Luckily, there's already a nu-highlight
command for syntax
highlighting commands, and a table
command for syntax
highlighting outputs. Shiki can be run in Node and the
capture-website
library can be used to take a screenshot. The rest is mostly formatting
and plumbing to make it work.
Start by following the
setup instructions. If you only want to show the output, pipe it to
nu-shiki
and you should get a
~/Downloads/screenshot.png
file generated for you. For
example, you might run the following command:
and get the following generated image.
It's also possible to show the command in the image by passing it explicitly:
which then renders the following image.
An alternative to this approach is to use --eval
on a command
string:
and the command will be evaluated for its output.
Note there are some caveats with
--eval
, especially around syntax highlighting.
If you have a long pipeline, the --format
option can format
it for you:
so that top-level pipes are put on separate lines. Note this uses some crude parsing that won't always work. If you pass the command and output separately, you always have the option to manually format the command.
Using the --lang
option, it is also possible to render code
in any language supported by Shiki. For example, the CSS image earlier in
the post was generated with the following command. The full
list of supported languages is
available on the Shiki website.
I experimented with nu -c
(similar to eval
in
Bash) to pass the command as a string
and then evaluate it.
Unfortunately, there were some issues and disadvantages with this
approach, which meant there was a case to pass the command and output
separately.
nu -c
returns
a byte stream).
stderr
you want to
show.
Update on October 14, 2025: after discussions with a colleague, the
--eval
option has been added and an example has been included
above. Note that syntax highlighting and colors may not always render as
expected with this option.
Hopefully you find nu-shiki useful. Let me know if you spot any mistakes!