If you're thinking about bookmarking or linking this page, maybe go for the main config instead. I try, but down here in the details it's a bit of a mess. Individual files get renamed. Lots.

Nushell Environment Config File


Started from the default env.nu prepared by Nushell, and expanding steadily from there.

My Nushell prompt

Start with a couple functions to decorate the left and right side of my shell prompt. Starship provides the left prompt decoration.

def create_left_prompt [] {
  starship prompt --cmd-duration $env.CMD_DURATION_MS $'--status=($env.LAST_EXIT_CODE)'

The right side is a basic date stamp.

def create_right_prompt [] {
    let time_segment = ([
        (date now | date format '%m/%d/%Y %r')
    ] | str collect)


Finish setting up prompt decorations with the appropriate environment variables.

let-env STARSHIP_SHELL = "nu"
let-env PROMPT_COMMAND = { create_left_prompt }
let-env PROMPT_COMMAND_RIGHT = { create_right_prompt }

Default environment variables for the assorted prompt indicators, showing current prompt state.

let-env PROMPT_INDICATOR = { "" }

Mapping to and from non-Nu environment variables

The Nushell $env.PATH is a list, but it interacts with systems that use delimited strings for $PATH and some other variables. $env.ENV_CONVERSIONS provide callbacks for mapping to and from Nu’s needed environment variables defined by the system in POSIX or other environments.

  "PATH": {
    from_string: { |s| $s | split row (char esep) }
    to_string: { |v| $v | str collect (char esep) }
  "Path": {
    from_string: { |s| $s | split row (char esep) }
    to_string: { |v| $v | str collect (char esep) }

Nushell script and plugin locations

$env.NU_LIB_DIRS specifies where I keep my Nushell scripts.

let-env NU_LIB_DIRS = [
    ($nu.config-path | path dirname | path join 'scripts')

$env.NU_PLUGIN_DIRS is where I want Nushell plugins kept.

let-env NU_PLUGIN_DIRS = [
    ($nu.config-path | path dirname | path join 'plugins')

Path management

a function to prepend paths to $env.PATH

Environment variable management is a bit stricter in Nu than other shells I’m used to. You can redefine $env entries at the top level of your script:

# - PATH redefinition example

let-env PATH = ($env.PATH | prepend '/some/path')

But since (almost) every block gets its own copy of the environment

def-env ensure-path [new-path: string] {
  let full-path = ($new-path | path expand)
  let updated-env-path = (
    if $new-path in $env.PATH { $env.PATH }
    else {
      $env.PATH | prepend $full-path
  let-env PATH = $updated-env-path

This lets me inch a little closer to definining my workflow environment in Nu.


(ensure-path "~/.volta/bin")

Support libraries

I still haven’t worked my way up to creating proper modules yet. Just some support functions I put in their own files. source runs before file eval, so interpolating or other conveniences are no good.

source /home/random/.config/nushell/lib/work.nu
source /home/random/.config/nushell/lib/task.nu

That’s stuff for work and #taskwarrior. I’ll break the non-work stuff down here some other time.


Playing with #logseq in Nushell, so I have a quick function using jet to help display lq results.

def from-edn [] {
  $in | str collect | jet --to json | from json