1---2title: "Notebooks"3sidebar_position: 34---56# Notebooks78A notebook is a tab of the workbook, beside its sheets, that holds cells9rather than a grid: code cells of nushell, each with its output under it,10and note cells of Markdown. You run the cells you choose, in the order11you choose, as in Jupyter; any output can go to a sheet, where formulas,12charts and pivots read it and it follows the cell's next run.1314```nu15files = ls | where type == file16$files | where size > 1kb | sort-by size --reverse17```18192021Open one from a shell with `012 nu`, or from nushell with `sheet nu`22(`sheet` comes from 012's nushell module: [Install the `sheet`23command](README.md#install-the-sheet-command)):2425```sh26012 nu # a new notebook, its first cell ready to type in27012 nu work.012 # the workbook's notebook, made if it has none28```2930In any workbook, **Data > Shell > Open notebook** (or the palette)31shows the workbook's notebook, or adds one after the sheet shown. A32notebook's tab is marked `❯`. Cells run `nu` as a separate process, so33[nushell](https://www.nushell.sh/book/installation.html) must be34installed; without it, a cell's output says so and the rest of 01235works as before.3637## Cells3839The tab looks and works like Jupyter's: a toolbar over the cells, a40code cell's pipeline in a box with its prompt at the left and a `▶` that41runs it at the right, its output under it, and note cells drawn as text.4243444546### Reading a cell4748Every state shows in words or marks as well as in color, so a notebook49reads the same on a terminal without it:5051| Where | Shows |52|---|---|53| The tab | `❯` before the notebook's name |54| Left of the cells | A bar at the active cell, blue in command mode and green in edit mode, and a thinner one at the others selected ([Keys](#keys)) |55| The box | Light lines, and heavy ones around the cell being edited |56| The prompt | How many runs came before this one: `[2]:`, `[*]:` while it runs, `[ ]:` before it has; `Out[2]:` marks the output of that run |57| The box's top border | The cell's name at the left, and at the right how its run stands (below): `waiting`, `running`, `● live` and the rows printed for a cell run as a [stream](#streams), ✓ and how long it took, `failed`, `stale`, or `saved` for an output read from the file |58| Right of the box | `▶` runs the cell, `■` stops it while it runs |59| The output | What it is ([below](#outputs)): a table or a record as a grid, its column names where a sheet has letters; `×` before an error; `output hidden`; which rows show in its window. Worked in, `OUTPUT` in the mode indicator, the bar left of it green, and its pointer and selection in reverse video, as on a sheet ([Outputs as grids](#outputs-as-grids)) |60| The context line | What the cell reads and how others read it (`big: reads $files; read as $big, nu.big in formulas`), the keys that apply, and what nu says about the cell being written, underlined curly in the cell ([Writing a cell](#writing-a-cell)) |6162A cell's run goes through these states:6364```mermaid65stateDiagram-v266 notrun: not run67 waiting: waiting68 running: running69 done: ✓ and how long it took70 failed: failed, and nu's message under it71 stale: stale72 [*] --> notrun73 notrun --> waiting: Shift+Enter, Ctrl+Enter, F974 waiting --> running: the cell before it ends75 running --> done76 running --> failed: an error, or ii77 done --> stale: a cell it reads runs again, or its source changes78 stale --> waiting: run again79 failed --> waiting: run again80 done --> waiting: run again81```8283A source is shown whole: a line too long for the screen wraps before a84pipe where it can, its next rows indented.8586### Outputs8788Outputs are drawn by what they are, with values formatted as cells89([Types](types.md)):9091| Output | Shows |92|---|---|93| A table (a list of records) | 012's grid ([Outputs as grids](#outputs-as-grids)): its columns headed by their names and fitted to their values, its rows numbered from 1 |94| A record | The same grid of two columns, `field` and `value`, a field a row |95| A list | Its items, numbered from 0, as nushell numbers them |96| Text | Its lines, wrapped |97| A value | As a cell shows it: `4.2 kB`, `9/27/2026 11:27:31` |98| An error | `×` and nushell's message, then its help line, without an `Out` prompt |99100A long output scrolls in a window of its own, 10 rows high, so the cells101under it stay where they are: with the output selected, Up and Down102scroll it before they move on, the wheel scrolls the window under the103mouse, and its last line says which rows show (`rows 11 to 20 of 45`).104`O` shows every row instead, and again the window; `o` hides the output105to one line, and again shows it, as does a click left of it. **Data >106Shell > Clear output** clears the selected cells' outputs, **Clear107outputs** every one.108109```mermaid110stateDiagram-v2111 window: a window of 10 rows, scrolled112 whole: every row113 hidden: one line, output hidden114 [*] --> window115 window --> whole: O116 whole --> window: O117 window --> hidden: o, or a click left of it118 whole --> hidden: o119 hidden --> window: o120```121122**Enter** on any other output, or a double click, opens it full-screen,123its lines scrolled with the arrows; Esc (or `◀ Back`) goes back.124125### Outputs as grids126127A table or a record is drawn as 012's own grid, the one a sheet has:128the values are the cells [sending it to a sheet](#send-to-a-sheet)129makes, each in the format of its type (sizes as `4.2 kB`, durations,130dates), right-aligned numbers, fitted columns and the grid's row131numbers, with the table's column names where a sheet has letters.132133**Enter** on the output, or a click in it, works in it (the mode134indicator says `OUTPUT`, and the bar left of it turns green, as for a135cell edited): an active cell moves with the arrows, and the grid's keys,136menus and mouse work on it as on a sheet, in its window:137138139140141- Shift+arrows, Ctrl+A or a drag select a range, and the status line142 shows its Sum, Avg and Count; Ctrl+C copies it, as TSV to the system143 clipboard and with its formats for Ctrl+V on a sheet.144- **Data > Sort sheet** (or the column's right-click menu) sorts by the145 active column, **Data > Create a filter** puts `▾` on each column's146 name, and Alt+Down (or a click on `▾`) opens the column's filter;147 Ctrl+F finds.148- Drag the right edge of a column's name, or **Format > Column width**,149 to resize it; Shift+wheel scrolls a wide table sideways; the names150 stay on top as the rows scroll.151- Ctrl+Z undoes a sort, a filter or a width; typing, Del, paste and152 formats are refused, as they'd change the output: `G` sends it to a153 sheet, where its copy can change.154- **Enter** shows the grid full-screen, where it all works the same;155 **Esc** deselects, then goes back from full-screen, then back to the156 notebook.157158```mermaid159stateDiagram-v2160 selected: output selected (NOTEBOOK)161 window: its grid, in its window (OUTPUT)162 full: its grid, full-screen (OUTPUT)163 selected --> window: Enter, a click in it164 window --> full: Enter, a double click165 full --> window: Esc166 window --> selected: Esc167```168169Sorting and filtering act on the grid's copy: the output, what later170cells read as `$name`, doesn't change, and running the cell again171draws its new output afresh.172173**Insert > Chart**, **Data > Pivot table** and the frequency table174(Alt+Shift+F) on the grid make them where charts and pivot tables live,175on a sheet: the output is [sent to a sheet](#send-to-a-sheet) first (a new176one named after the cell, unless it's on one already), and the command177runs there on the columns selected in the grid, every row under the178header. A chart drawn under the output would have to squeeze into the179notebook's column and scroll with the cells; on the sheet it has room,180its editor, images where the terminal draws them, and it follows the181cell's next run, as the region it charts does.182183### Note cells184185Note cells are Markdown: headings, **bold**, *italic*, `code`, links (the186terminal opens them), lists and quotes. They're drawn as text, without a187box or a prompt, and show their Markdown in a box only while edited.188189## Keys190191Like Jupyter, a notebook has two modes. In command mode (the mode192indicator says `NOTEBOOK`) keys act on cells; in edit mode (`EDIT`) they193type into the selected cell.194195```mermaid196stateDiagram-v2197 [*] --> Command198 Command --> Edit: Enter, !199 Edit --> Command: Esc200 Edit --> Command: Shift+Enter or Ctrl+Enter runs201 Command --> Output: Enter on an output202 Output --> Command: Esc203```204205The bar left of the active cell and the box's lines say which mode206you're in ([Reading a cell](#reading-a-cell)). Shift+Up and Shift+Down207(or `K` and `J`, or Shift+click) select the cells passed over as well,208and the commands below that act on "the cells" act on all of them: run,209delete, copy, cut, move, make notes or code, hide or clear outputs.210211| Key | In command mode |212|---|---|213| Up, Down, `j`, `k` | Move between cells, stopping at each output; on an output, scroll its window first |214| Shift+Up, Shift+Down, `K`, `J` | Select the cells passed over too |215| Home, End, PgUp, PgDn | The first cell, the last, a screen up or down |216| Enter | Edit the cell; on a table or record output, work in its grid; on another, open it full-screen |217| Shift+Enter | Run the cells and select the next, adding one at the end |218| Ctrl+Enter, `r` | Run the cells, staying on them |219| Alt+Enter | Run the cells and add a code cell under them |220| F9 | Run every cell |221| `a`, `b` | Add a code cell above, below |222| `!` | Add a code cell below and edit it |223| `dd` | Delete the cells |224| `z` | Undo, bringing back deleted cells (as Ctrl+Z) |225| Alt+Up, Alt+Down (or Ctrl+Shift+Up, Ctrl+Shift+Down) | Move the cells up or down |226| `m`, `y` | Make the cells notes (Markdown), or code |227| `c`, `x`, `v`, `V` | Copy, cut the cells; paste below, above |228| `n` | Name the cell |229| `o`, `O` | Hide the output, or show it again; show every row, or the window again |230| `G` | Send the output to a sheet |231| Ctrl+G | Go to a cell by its number, name, code or heading |232| `f` | Run the cell as a stream, until it's stopped ([Streams](#streams)) |233| `ii` | Stop: kill the cell running, forget those waiting, and stop every stream |234| `00` | Restart: stop, clear every output, count runs from 1 |235236| Key | In edit mode |237|---|---|238| Esc | Keep what's typed and go back to command mode |239| Shift+Enter, Ctrl+Enter, Alt+Enter | Run, as in command mode |240| Enter | A new line, as indented as the one before |241| Up, Down, Home, End | Move by the lines on screen, wrapped lines too |242| Ctrl+A, Ctrl+E | The start, the end of the line |243| Tab | Complete the word at the caret: a cell's `$name`, `$selection`, a linked file, then what nu completes there (commands, flags, paths); one completion goes in at once ([Writing a cell](#writing-a-cell)) |244| F1 | The help of the command at the caret, with its page in nushell's docs ([Writing a cell](#writing-a-cell)) |245246A terminal without the kitty keyboard protocol sends Shift+Enter and247Ctrl+Enter as Enter ([Keys the terminal has to tell248apart](../reference/keys.md#keys-the-terminal-has-to-tell-apart)): there249Esc then `r` runs the cell, and Alt+Enter runs it and adds one under it.250251Every action is a command, in **Data > Shell**, the palette and the252shortcuts (Ctrl+/), and File, Edit and the sheet tabs work as anywhere;253commands for a sheet's cells are off on a notebook's tab. Changes to254cells are undo steps, as any edit is.255256### Toolbar and mouse257258The toolbar runs the commands Jupyter's does: `▶ Run` (the cells, then259the next), `■ Stop`, `↻ Restart`, `▶▶ Run all`, `+ Add`, `✂ Cut`, `⧉ Copy`,260`⎘ Paste`, and `Code ▾` or `Markdown ▾`, which makes the cells either. Each261shows its key where the width allows. At the right, `nu ○ idle`, `nu ●262busy` with how many cells wait, or `nu ⊘ off` where cells don't run,263stands for Jupyter's kernel; `reactive` beside it says the notebook is.264While every cell runs, the view follows the cell running until you265scroll.266267The mouse works as in JupyterLab: a click selects a cell and a click in268a code cell's box edits it with the caret where you clicked; `▶` runs the269cell and `■` stops it while it runs; a double click edits a note or opens270an output full-screen; the wheel scrolls an output's window, then the271notebook; right-click opens the cell menu. All of them are listed in272[Keys and mouse](../reference/keys.md#mouse).273274### Moving around275276**Ctrl+G** (Go to cell) lists every cell by its number, name and first277line, and the notes' headings, to jump to by typing any of them. **View278> Table of contents** lists the headings alone, indented by level, as279Jupyter's table of contents.280281## Writing a cell282283The cell being written is read by nu itself, as nushell's own prompt284reads what you type: once typing pauses, 012 asks `nu --ide-ast` what285each word is and colors it (commands, strings, variables, numbers,286keywords, operators; flags stay plain), and `nu --ide-check` what's287wrong. A problem is underlined with a curly line, and with the caret on288it the context line says what nu said:289290291292293Tab asks `nu --ide-complete` too, after the notebook's own names, so it294completes flags, subcommands and paths as well as cells and commands.295296Once the caret rests on a word, the context line says what it is, so297writing a cell doesn't mean leaving it for `help`. On a command, `nu298--ide-hover` gives its signature (its parameters with their types,299then its flags) and what it does; on a flag, what the flag does. Where300the line is short, the flags give way first, then the types, then the301end of the description. A problem at the caret takes the line instead.302303304305306F1 opens the command's whole help over the notebook: what it does, a307link to its page in nushell's docs, its usage, flags, parameters, input308and output types and examples. Up and Down scroll it, Esc goes back to309the cell. F1 on a word that isn't a command opens the keyboard shortcuts,310as it does anywhere else.311312313314315On a `$name` another cell binds, the line says the cell and the shape316of its value as it last ran (`$files: table, 12 rows × 4 columns from317cell 3`), from the notebook's own outputs without asking nu; on318`$selection`, a linked file or `$sheet.A1:C9`, what it reads; on a319variable the cell binds itself with `let`, the type nu gives it.320nu doesn't know the variables a notebook binds, so it's asked about the321cell with `$name` for each name the cells assign and each linked file,322`$selection` and `$sheet` declared before it; a `$sheet.A1:C9` range323reads as one variable, and the cell's `name =`s ([Names and324$name](#names-and-name)) aren't part of what nu reads, so what nu says325is where it points in the cell.326327Questions to nu run in the background and never on each key: one328process for each question after a pause, at most two at a time, each329stopped once the text changes and after a second and a half. Until nu330answers, the cell shows 012's own highlighting, and what's unchanged331keeps nu's colors, so nothing flickers or moves. 012 falls back to its332own highlighting and names, without saying so, when:333334- nu isn't installed, or is older than 0.100;335- nu timed out three times in a row (asked again in the next session);336- the cells couldn't run without asking: a file from another computer337 not yet trusted ([Saving and trust](#saving-and-trust)), `shell =338 off`, or [012 serve](../terminal/ssh.md#notebooks) without339 `serve-shell`.340341nu reads the cell without your `config.nu` or its standard library, so342your own commands aren't known to it; they still run when the cell does343with `nu-config`.344345## Running346347Cells run in the background, one at a time, so the screen stays live:348the one running shows `[*]` and those after it `waiting`. **Data >349Shell** runs one cell, every cell (F9), the cells above the selected350one or it and those below; each runs after the cells it reads. A cell351that fails stops the rest.352353Each cell runs as `nu --no-config-file -c`, so your aliases and custom354commands aren't there unless `nu-config` is on355([nushell's configuration](https://www.nushell.sh/book/configuration.html)).356A cell stops after `nu-timeout` (30 seconds unless set); `ii` stops it357sooner.358359### Streams360361A pipeline that never ends, such as following a log or `watch`ing a362folder, runs as a stream: `f` (**Data > Shell > Run as stream**) runs363the selected cell until you stop it, and every value it yields reaches364the cell's output as soon as nu prints it, and the sheet the output was365[sent to](#send-to-a-sheet) as rows under its header:366367```nu368log = tail -f app.log | lines | parse '{time} {level} {msg}'369changes = watch . --glob=*.csv --quiet370```371372While it runs, the cell's box says `● live` with how many rows it has373printed, and the toolbar how many cells stream; streams run beside the374cells run once, each on its own, without `nu-timeout`. `ii` (or `■`)375stops them all, keeping what they printed; running the cell once (`r`)376stops its stream first. A stream that ends on its own keeps its output377as a run does, and one that fails says why. A cell of several statements378streams its last one's values; the names its earlier lines assign stay379its own, as a stream hands later cells only its output.380381The output keeps a stream's last 10,000 values; a sheet it was sent to382keeps every row, up to `max-cells`. The rows arrive as the change383stream does for a [followed file](../files/following.md), outside the384undo history.385386A table's grid takes the rows as they arrive, under those it shows, so387what you've done in it stays: the pointer, the selection, a filter388(which covers the new rows) and the rows as sorted, the new ones under389them. Its columns widen to fit longer rows, never narrowing, and wait390while you're in the grid so nothing shifts under the pointer; a column391you resized keeps its width. Past 20,000 rows the grid starts again392from the rows the output keeps.393394## Names and $name395396A cell holds one statement or several, a line each (or apart by `;`),397as a nushell script does; a line starting with `|` goes on with the398pipeline above it. `name =` before a pipeline, on any line, assigns `name` as399nushell's `let` does, and the cell's later lines read400it as `$name`. `#` starts a comment to the end of the line, outside a401string, as in nushell: a commented-out line assigns and reads nothing.402403As in nushell and Jupyter, the cell's output is its last statement's404value, and the names work across cells by one rule:405406- **The cell's name is its output's.** When the last statement is407 an assignment (`name =`), the cell is named `name`; otherwise it has no408 name until `n` names it, which puts `name =` before its last409 statement. Other cells read the output as `$name`, and formulas on410 any sheet as `nu.name`, or a column of it as `name[column]`, once411 it's [sent to a sheet](#send-to-a-sheet).412- **Every name assigned goes to later cells.** `$files` in another413 cell reads the `files` a cell's earlier line assigned, as it was at414 the end of that cell's run. A cell's name comes first: `$sales` reads415 the cell named `sales`, and only when no cell is named so, the first416 cell assigning `sales`.417- **A cell's own names come first in it.** `$files` after the line418 assigning `files` reads the cell's own, not another cell's, and isn't419 a cell it reads.420421```nu422files = ls | where type == file423$files | where size > 1kb | sort-by size --reverse424```425426This cell has no name (its last line assigns none) and reads no cell;427its output is the big files, and later cells read `$files` too. Split428over cells, each named after its output:429430```nu431files = ls432big = $files | where size > 1kb433$big | get name | str join ", "434```435436The context line says what a cell reads, the names it sets for later437cells and its own name (`reads $files; sets $big`). A file keeps each438cell's output, not the other names it assigned: after opening one, a439cell reading such a name runs the cell assigning it first, as it does440a cell that hasn't run.441442A name is letters, digits and `_`, not starting with a digit or `__`;443`in`, `env`, `nu`, `it`, `selection` and `sheet` are taken. Two cells444can't share a name: the second says so and doesn't run until it's445renamed.446447What a cell reads decides the order cells run in: each after the cells448it reads, and a cell that hasn't run first when one reading it runs. A449cell reading itself, directly or through others, doesn't run.450451```mermaid452flowchart TD453 files["files = ls"] -->|$files| big["big = $files | where size > 1kb"]454 app["a linked file, app.csv"] -->|$app| errors["errors = $app | where status >= 500"]455 big -->|G sends it to a sheet| region["the region big, on a sheet"]456 region --> sum["=SUM(nu.big)"]457```458459A cell reads the sheets two ways, each a table:460461| In a cell | Is |462|---|---|463| `$selection` | The range selected on the sheet shown last before the notebook, with its first row as the header |464| `$sheet.A1:C9`, `$sheet.Sales!A1:C9`, `$sheet.'Q1 data'!B2:B40` | That range, of the sheet shown last or the sheet named |465| `$app` | A [linked file](../files/following.md) named `app`, its rows as they are when the cell runs |466467They reach nu as NUON in a file it reads, never as text spliced into468the pipeline, so types survive ([Types](types.md)): sizes stay sizes,469dates stay dates, and currency and percentages, numbers in nu, take470their columns' formats again when the output is sent to a sheet471([Currency and percentages](types.md#currency-and-percentages)).472473### Stale outputs and reactive notebooks474475Running a cell again makes the outputs of the cells that read it,476directly or through others, `stale`: they were made from what it printed477before. So is a cell's own output once its source is changed.478479```mermaid480flowchart TD481 run["files runs again"] --> stale["big, and cells reading big: stale"]482 stale -->|reactive off| you["run them when you want"]483 stale -->|reactive on| again["they run again, each after what it reads"]484 you --> fresh["fresh outputs"]485 again --> fresh486```487488**Data > Shell > Reactive notebook** (off unless turned on, saved489with the notebook) runs them again whenever a cell they read runs.490491## Send to a sheet492493`G` sends the selected cell's output to a sheet: a new sheet named after494the cell, or a cell of a sheet you pick. There it's a region named after495the cell, italic as a linked file's rows are, that formulas read as496`nu.name`, header row included (`=SUM(nu.big)`, `=VLOOKUP("go.mod",497nu.files, 3, FALSE)`), and charts and pivot tables use. It's also a498[table](../sheets/tables.md#notebook-outputs-and-linked-files) by the499cell's name, read by column: `=SUM(big[size])`, `=COUNTIF(app[status],500500)`, with `big` alone its rows under the header. A cell without a501name is given one first. On the region's cells the context line says502whose output they are (`Output of big`).503504```mermaid505sequenceDiagram506 participant C as Cell big507 participant R as Region big on a sheet508 participant F as =SUM(nu.big)509 C->>R: G sends the output's rows510 R->>F: recalculates511 C->>C: runs again512 C->>R: the new rows replace the old513 R->>F: recalculates514```515516Like an [array's spill](../formulas/arrays.md#spilled-cells), its cells517can't be typed over: **Data > Shell > Freeze output** turns them into518plain values, and **Remove output** takes them off the sheet. Undo takes519back sending it, and the rows come back from the cell's output whenever520undo brings the region back.521522## Saving and trust523524The file keeps the cells and their outputs as NUON525([format](../files/format.md#notebooks)), so opening it shows every526output without running anything; the heads say `saved`. An output larger527than `nu-save-cell-kb` (1 MB), or past `nu-save-notebook-kb` (8 MB) for528all of them, is left out: the cell shows `not saved; run to see`, and529saving says which.530531Opening a file never runs its cells. Like532[macros](../sheets/macros.md#macros-from-other-computers), a file's cells533run as you, with your files, so a notebook saved on another computer534asks once before its cells run:535536```mermaid537sequenceDiagram538 participant You539 participant N as The notebook540 participant Nu as nu541 You->>N: open a file saved on another computer542 N-->>You: its cells and saved outputs, nothing run543 You->>N: Shift+Enter, or F9544 N-->>You: Run this file's notebook cells?545 You->>N: Enter546 N->>Nu: the cells, one at a time547 Nu-->>N: their outputs548```549550Cells you write in a notebook made here run without asking. The options,551in [Configuration](../reference/config.md#nushell-notebooks):552553| Option | Default | Does |554|---|---|---|555| `shell` | `ask` | `ask` as above; `on` never asks; `off` runs no cells |556| `nu-timeout` | `30s` | Stops a cell that runs longer; `0` lets it run until `ii` |557| `nu-config` | `false` | Runs cells with your `config.nu` and `env.nu` |558| `nu-save-cell-kb`, `nu-save-notebook-kb` | `1024`, `8192` | How much of the outputs a file keeps |559560[012 serve](../terminal/ssh.md#notebooks) shows notebooks and their561saved outputs, but runs no cells unless the server's `serve-shell` is on.562563### Notebook sheets564565A file with the notebook sheets of earlier versions of 012, whose566pipelines were typed at a prompt on the formula bar, opens with each of567those pipelines as a code cell of the workbook's notebook, named as the568region was. Their tables stay where they were on the sheet, as the569cells' outputs sent there, so formulas reading `nu.r1` keep working once570the cells run; a note on opening says which sheets were converted.