Help us shape the future of Go! Take the 2026 Go Developer Survey

notebook

module
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 23, 2026 License: BSD-3-Clause

README ΒΆ

go-notebook/notebook

notebook β€” go-notebook

Docs License Go Coverage

Go notebooks with native speed, kept values and a reproducible order.

🌐 Website Β· πŸ“š Documentation

A notebook is a Markdown file whose ```go blocks are cells β€” and ```ruby blocks too, in a pure-Go Ruby with the same numerical libraries, sharing their variables with the Go cells. The kernel:

  • compiles it into a real Go program, so cells run at native speed;
  • orders the cells by what they use, worked out from the code itself as marimo does for Python, not by the order you ran them in;
  • runs only what changed. A cell whose code and inputs did not change keeps its result, and its values are handed over instead of being computed again. That holds across rebuilds and across runs: results and values are kept on disk.
# Spectrum

```go
import "math"

n := 1_000_000
```

The sum below runs once; editing the last cell does not run it again.

```go
sum := 0.0
for i := 1; i <= n; i++ {
	sum += 1 / float64(i*i)
}
```

```go
math.Sqrt(6 * sum)
```
$ notebook run spectrum.md
── cell 0 (line 4, ran in 11Β΅s)
── cell 1 (line 12, ran in 2.065ms)
── cell 2 (line 19, ran in 30Β΅s)
   3.1415916986605086
$ # change the last cell to math.Pi - math.Sqrt(6*sum), then:
$ notebook run spectrum.md
── cell 0 (line 4, kept)
── cell 1 (line 12, kept)
── cell 2 (line 19, ran in 48Β΅s)
   9.54929284535666e-07

The second run is a new process: sum comes back from the kernel's store, it is not summed again.

Use

go install github.com/go-notebook/notebook/cmd/notebook@latest

notebook run analysis.md     # run it, print each cell's results
notebook html analysis.md    # run it, write analysis.html (no scripts, no external resources; $\TeX$ math typeset by go-tex)
notebook watch analysis.md   # run it on every save and keep analysis.html current
notebook serve analysis.md   # the same in your browser at http://127.0.0.1:8888: edit cells there too

Edit the .md in any editor, or in the page serve shows (double-click a cell, Ctrl/⌘+Enter to save): the file is the only source of truth, and only what changed runs again.

Flags are POSIX, and each verb lists its own with notebook <verb> --help:

Flag Verbs
-o, --output FILE html, watch the page to write (default: the notebook's name with .html)
--addr HOST:PORT serve where to listen (default 127.0.0.1:8888)
--interval D watch, serve how often the file is looked at (default 300ms)
-t, --timeout D all stop a cell that runs longer (default: no limit)
-m, --memory MiB all stop a cell whose worker holds more heap (default: no limit)
-w, --work DIR all the work directory (default: under the user cache directory)
--runtime-src DIR all run against a go-notebook source tree instead of a released runtime

Releases up to v0.3 read flags with one dash (-timeout 30s); that spelling is still accepted, with a note on stderr.

examples/spectrum.md finds two tones in Gaussian noise with go-ndarray (arrays, fft.RFFT, a seeded generator that gives NumPy's numbers for the same seed) and draws the signal and its spectrum with go-plot.

Cells

A cell is Go with statements allowed at the top level:

import "strings"

func words(s string) []string { return strings.Fields(s) }

w := words("to be or not to be")
len(w) // the final expression is shown
  • Names defined at the top level are shared with every cell. Each name is defined by one cell, and a cell may not assign to another cell's variable. That is what makes the order a function of the code.
  • Names starting with _, and err, stay local to their cell.
  • A final call returning (value, error) shows the value; a non-nil error fails the cell.
  • A value with a Display() map[string][]byte method shows itself as HTML, SVG or PNG.
  • Errors point at the notebook's own lines. A panic stops the cells that read the failing one, and they say why.

Ruby cells

A ```ruby block runs in rbgo, a Ruby written in Go, with the go-scikit bindings: Stats, Special, Optimize, Integrate, DataFrame and Plot over the same Go libraries, and rbgo's NDArray. Ruby cells share one interpreter, so their top-level locals persist from cell to cell. The two languages share their variables:

  • A Go variable a Ruby cell reads becomes a Ruby local of the same name. A []float64 becomes an Array, and an *ndarray.Array stays the same NDArray.
  • A Ruby local a Go cell reads becomes a Go variable typed from its value: a Float is a float64, an Array of Floats a []float64, an NDArray an *ndarray.Array, a fitted Stats::Gamma the stats.Gamma itself.

Dependencies, caching and re-runs work across languages as for Go alone: a Ruby cell re-runs only when it or a cell it reads changes. The last expression shows its inspect, and a Plot figure shows as SVG. examples/mixed.md draws data in Go and fits and plots it in Ruby; the exact rules are in docs/design.md.

A notebook runs with your rights, in either language. Every cell runs in a worker process of its own: --timeout 30s kills a worker whose cell runs longer, and --memory 512 stops one whose cells hold more than 512 MiB of Go heap; the cell fails, and the next run starts a new worker. Both are off by default (what a cell can do, and what stops it).

How it works

format parses the Markdown and analysis builds the dependency graph from the syntax. gen writes the Go program, type-checking cell by cell to learn the types of shared variables. kernel compiles it into a worker, drives it through runtime, and keeps results and values under a hash of each cell's code and inputs. export writes the HTML page. The reasons for each choice, and what is not done yet, are in docs/design.md; the documentation covers the cell rules, the command and the kernel in more detail.

It is part of an ecosystem built for it: go-ndarray (N-dimensional arrays in thirteen dtypes, with FFT, linear algebra, and random numbers bit-identical to NumPy's for the same seed), go-plot (figures, with TeX labels), and, in progress, go-numerics (special functions, optimisation, integration), go-statistics and go-dataframe.

License

BSD-3-Clause. See LICENSE.

Directories ΒΆ

Path Synopsis
Package analysis finds what each code cell of a notebook defines and uses, and orders the cells by those dependencies.
Package analysis finds what each code cell of a notebook defines and uses, and orders the cells by those dependencies.
cmd
notebook command
Command notebook runs Go notebooks: Markdown files whose ```go blocks are cells.
Command notebook runs Go notebooks: Markdown files whose ```go blocks are cells.
Package export renders a notebook and its results as a standalone HTML page: the prose as Markdown, each code cell with what it printed, showed or failed with.
Package export renders a notebook and its results as a standalone HTML page: the prose as Markdown, each code cell with what it printed, showed or failed with.
Package format reads and writes notebooks.
Package format reads and writes notebooks.
Package gen turns a notebook's code cells into a Go program: the worker the kernel compiles and drives.
Package gen turns a notebook's code cells into a Go program: the worker the kernel compiles and drives.
Package kernel runs notebooks.
Package kernel runs notebooks.
Package runtime is linked into every compiled notebook.
Package runtime is linked into every compiled notebook.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL