---
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
```