--- name: observable-notebook-kit description: Create, edit, and build Observable Notebooks using Notebook Kit. Use when working with .html notebook files, generating static sites from notebooks, querying databases from notebooks, or using data loaders (Node.js/Python/R) in notebooks. Covers notebook file format, cell types, CLI commands, database connectors, and JavaScript API. --- # Observable Notebook Kit Observable Notebook Kit is an open-source CLI and Vite plugin for building static sites from Observable Notebooks. ## File Format Notebooks are `.html` files with this structure: ```html My Notebook ``` ### `` Attributes - `theme` - colorway: `air` (default), `coffee`, `cotton`, `deep-space`, `glacier`, `ink`, `midnight`, `near-midnight`, `ocean-floor`, `parchment`, `slate`, `stark`, `sun-faded` - `readonly` - disallow editing ### `` as `<\/script>`. ## CLI Commands Install: `npm add @observablehq/notebook-kit` ### Preview ```sh notebooks preview --root docs notebooks preview --root docs --template docs/custom.tmpl ``` ### Build ```sh notebooks build --root docs -- docs/*.html ``` Output goes to `.observable/dist`. ### Download Convert Observable notebook URL to local HTML: ```sh notebooks download https://observablehq.com/@d3/bar-chart > bar-chart.html ``` ### Query Run database query manually: ```sh notebooks query --database duckdb 'SELECT 1 + 2' ``` ## JavaScript in Notebooks ### Expression vs Program Cells Expression cell (implicit display): ```js 1 + 2 ``` Program cell (explicit display): ```js const foo = 1 + 2; display(foo); ``` ### Key Built-ins - `display(value)` - render value to cell output - `view(input)` - display input, return value generator - `FileAttachment("path")` - load local files (same/sub directory only) - `invalidation` - promise for cleanup on re-run - `visibility` - promise when cell visible - `width` - current page width - `now` - current time ### Standard Library - `Inputs` - Observable Inputs - `Plot` - Observable Plot - `d3` - D3.js - `htl`, `html`, `svg` - Hypertext Literal - `tex`, `md` - tagged template literals ### Imports ```js import lib from "npm:package-name"; import {fn} from "jsr:@scope/package"; ``` ### Reactivity Top-level variables trigger re-runs. Promises auto-await; generators yield latest value. ```js const x = view(Inputs.range([0, 100])); ``` ```js x ** 2 // re-runs when x changes ``` ### Interpolation Use `${...}` in Markdown/HTML cells: ```md The answer is ${x * 2}. ``` ## Database Connectors See [references/databases.md](references/databases.md) for full configuration. ### Quick Setup SQL cells use `database` attribute. Default is `duckdb` (in-memory). ```html ``` ### Supported Databases - DuckDB (`@duckdb/node-api`) - SQLite (Node.js 24+ built-in) - Postgres (`postgres`) - Snowflake (`snowflake-sdk`) - BigQuery (`@google-cloud/bigquery`) - Databricks (`@databricks/sql`) Install drivers separately: `npm add @duckdb/node-api` ### Query Results - Auto-cached in `.observable/cache` - Re-run via Play button or Shift+Enter in Desktop - Delete cache file to refresh in Notebook Kit ### Dynamic Queries ```js const db = DatabaseClient("duckdb"); const data = await db.sql`SELECT * FROM t WHERE x = ${value}`; ``` ## Data Loaders Cells that run at build time via interpreter. Output cached in `.observable/cache`. ### Formats Text: `text`, `json`, `csv`, `tsv`, `xml` Binary: `arrow`, `parquet`, `blob`, `buffer` Image: `png`, `jpeg`, `gif`, `webp`, `svg` Other: `html` ### Node.js ```html ``` Requires Node.js 22.12+. Sandboxed with read-only access to notebook directory. ### Python ```html ``` Requires Python 3.12+. Uses `.venv` if present. ### R ```html ``` ## Page Templates Custom templates wrap built notebooks: ```html
``` Use `--template path.tmpl` with CLI. ## Project Setup Typical `package.json`: ```json { "dependencies": { "@observablehq/notebook-kit": "^" }, "scripts": { "docs:preview": "notebooks preview --root docs", "docs:build": "notebooks build --root docs -- docs/*.html" } } ``` ## Configuration Files - `.observable/databases.json` - database configs (keep out of git) - `.observable/cache/` - query/data loader results - `.observable/dist/` - built site Recommended `.gitignore`: ``` .observable ```