Zbook
Zbook is an intentionally small, keyboard-first notebook application. It keeps the useful core of Jupyter—real .ipynb files, IPython kernels, markdown, rich outputs, and a workspace tree—then adds a first-class local Codex panel and a focused uv environment workflow.
The design target is closer to Zed than JupyterLab: flat surfaces, restrained color, minimal persistent chrome, fast keyboard navigation, and no extension ecosystem to carry.
Working checkpoint
The main notebook loop is functional:
- the file tree is served by Jupyter's Contents API and is rooted at the configured workspace;
- notebooks can be created, opened in closable tabs, renamed inline by double-clicking a tab, deleted, uploaded, autosaved, and exported as
.ipynb; - open tabs, the active notebook, selected cell, panel visibility, and Vim preference are restored per workspace;
Ctrl/Cmd-Popens a workspace file picker andCtrl/Cmd-Shift-Popens the command palette;- the workspace and Codex panes are draggable, keyboard-resizable, and remember their widths across reloads;
- refreshing the workspace also reloads the active notebook from disk (after confirming before discarding local unsaved changes);
- folders can be selected and created, and arbitrary files can be uploaded;
- code cells execute on a real IPython kernel with streamed text, errors, HTML, and PNG output;
- Markdown cells render in place; code and Markdown editors have syntax highlighting, bundled JetBrains Mono typography, and optional Vim bindings; the UI and prose use bundled Inter;
- long outputs can be height-limited from the gutter without shrinking their code, scaled images expand to their native resolution on double-click with two-axis scrolling, and
#@title …gives a code cell a dedicated title row above its execution gutter and a whole-cell collapse toggle; these view preferences persist per workspace without changing the notebook file; - Run all, execution counts, interrupt, and keyboard execution commands work;
- the environment panel lists packages and installs or uninstalls them through serialized
uvoperations; - a fresh launch defaults to a scratch uv environment under
/tmp, preparesipykernel, and removes the scratch environment on shutdown; - workspace
.venvfolders are detected and can be selected live; a project folder or uv-venv path can also be entered manually; - the Codex panel uses the locally signed-in Codex CLI and ChatGPT subscription—no application API key—and streams turns through Codex App Server;
- Codex receives optional notebook/cell context and exposes live command/file activity plus any required approvals;
- Codex gets dedicated read/lock/apply cell tools: the read response advertises the current action inventory, relevant cells become visibly read-only across the full reasoning-and-editing turn, remaining locks release automatically at turn end, and edits are revision-checked, atomic, undoable, and saved without a shell/edit/refresh round trip; source-light reads plus
move_afterandswapoperations make reordering inexpensive; - each Codex cell edit gets an in-notebook review marker and a safe one-step undo until the notebook changes again;
- the Codex pane reads the installed CLI's model catalog and subscription rate limits, defaults to GPT-5.6-Luna with medium reasoning when available, and provides model/effort pickers, quota refresh, sign-in, and sign-out.
- Zbook-created Codex threads persist through App Server, are remembered per workspace, and can be resumed from the compact thread switcher with command/file/notebook activity restored and Zbook's private context augmentation kept out of the visible transcript.
This is still a focused checkpoint, not a JupyterLab replacement. Tabs share one workspace kernel and save before switching; non-notebook files are managed but not edited; and Jupyter widgets and arbitrary JavaScript outputs are not supported.
Architecture
React + CodeMirror 6
├─ Jupyter Contents / Kernel WebSocket APIs
├─ Zbook package-management API ── uv ── selected .venv
└─ Zbook Codex WebSocket ── codex app-server (stdio JSONL)
└─ dynamic cell tools ── revision-locked React notebook state
Jupyter Server ExtensionApp
├─ file boundary: configured workspace
├─ kernel: exact <venv>/bin/python
└─ static production frontend
Python owns processes, filesystem boundaries, and Jupyter integration. TypeScript owns interaction state and rendering. The selected notebook environment is deliberately separate from the app's own environment so installing a package cannot destabilize the server. Codex runs with workspace-write scope, while commands that need broader filesystem or network access still use the CLI's approval flow. The bridge follows the official Codex App Server protocol over a private authenticated WebSocket.
Run the checks
uv run ruff check src tests
uv run pytest -q
cd frontend && npm run build
Build the web client
Use Node.js 20.19 or newer:
cd frontend
npm install
npm run build
The Vite build is emitted into src/zbook/static/, where the Python application serves it.
Install and launch
Build the web client once, then install the local package as a uv tool:
uv sync --dev
cd frontend && npm install && npm run build && cd ..
uv tool install .
The installed command has a small preflight check and a dedicated launch command:
zbook check
zbook run
zbook run --workspace-dir /absolute/path/to/workspace
zbook run --ip 0.0.0.0 --port 8888
zbook run uses the current directory as its workspace and listens only on Jupyter's localhost default. Binding a wildcard or non-loopback address prints a highlighted security warning: remote clients that obtain access can execute notebook code and reach the selected workspace and Codex. 0.0.0.0 listens on every network interface, though actual reachability still depends on the host firewall and network configuration. Keep Jupyter authentication enabled.
The default kernel environment is a disposable uv venv under /tmp; a persistent uv environment can be selected from the environment panel while the app is running.
Jupyter Server options go after a -- passthrough boundary:
zbook run --workspace-dir /absolute/path/to/workspace --port 8890 -- \
--ServerApp.open_browser=False
Startup environment traits can be passed the same way when needed:
zbook run --workspace-dir /absolute/path/to/workspace -- \
--ZbookApp.venv=/absolute/path/to/project/.venv
For compatibility, Jupyter flags supplied without -- are still forwarded, but Zbook prints a highlighted warning showing the preferred form. The old direct form (zbook --ZbookApp.workspace=…) also remains available with a migration warning. During development, prefix these commands with uv run, such as uv run zbook check.
Releasing
Releases are built and published by .github/workflows/release.yml through PyPI Trusted Publishing. The PyPI publisher must match the honglu2875/zbook repository, the release.yml workflow, and the pypi GitHub environment.
For the first release, tag the current 0.1.0 commit after configuring the pypi environment and pending PyPI publisher:
git tag -a v0.1.0 -m "zbook 0.1.0"
git push origin v0.1.0
For subsequent releases, update the sole package-version source in pyproject.toml, review the lockfile, commit, and push the matching tag:
uv version 0.1.1
git add pyproject.toml uv.lock
git commit -m "Release 0.1.1"
git tag -a v0.1.1 -m "zbook 0.1.1"
git push origin main v0.1.1
The workflow rejects a tag that does not match the package version, rebuilds and verifies the committed web client, tests both distribution formats in isolated environments, and grants the publishing credential only to the final PyPI job. Published PyPI versions cannot be replaced; use a new version for every changed release.
Notebook key model
Shift-Escapeleaves an editor and enters notebook navigation mode.j/kor the arrow keys move between cells in navigation mode.Enteroriedits the selected cell.ainserts a code cell above;boroinserts one below. Hover or keyboard-focus the space between cells to choose Code or Markdown explicitly.Ctrl-Enterruns in place,Shift-Enterruns and advances, andAlt-Enterruns and inserts.- Vim bindings can be toggled from the status bar. Vim receives its keymap before the standard CodeMirror keymaps.
This two-level model avoids the classic conflict between Vim's modes and notebook-level commands: notebook navigation is a separate outer mode, and Vim operates only inside the active editor.
License
Zbook is released under the MIT License. The bundled Inter and JetBrains Mono fonts remain under the SIL Open Font License 1.1; their notices ship with the frontend.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file zbook-0.1.0.tar.gz.
File metadata
- Download URL: zbook-0.1.0.tar.gz
- Upload date:
- Size: 1.2 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
018a935de06322b3be7f1248217b45fd1b8b1bcdf4a60d5447bd9611ea2cdbcb
|
|
| MD5 |
44adfd93609e78f45690ed3af6dcf139
|
|
| BLAKE2b-256 |
7481efc8b8405c1a3c5394415c6d8b876feb08c20af78de6a9b5e7e20b9069b8
|
Provenance
The following attestation bundles were made for zbook-0.1.0.tar.gz:
Publisher:
release.yml on honglu2875/zbook
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
zbook-0.1.0.tar.gz -
Subject digest:
018a935de06322b3be7f1248217b45fd1b8b1bcdf4a60d5447bd9611ea2cdbcb - Sigstore transparency entry: 2568504886
- Sigstore integration time:
-
Permalink:
honglu2875/zbook@5746b80ba7cda9ae68d5340d6b699acb87dda2b3 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/honglu2875
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@5746b80ba7cda9ae68d5340d6b699acb87dda2b3 -
Trigger Event:
push
-
Statement type:
File details
Details for the file zbook-0.1.0-py3-none-any.whl.
File metadata
- Download URL: zbook-0.1.0-py3-none-any.whl
- Upload date:
- Size: 1.1 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
98ecbdd6b9067c58569c4b77b9bd25a4e888a5b0e5189947544e2b4cf6092853
|
|
| MD5 |
bff82656c2c2743336300de037b22ba4
|
|
| BLAKE2b-256 |
c4ffc0edc3817c067b014e4bcbd96dcc181e2fc4c15c40bf2d31651167f2905c
|
Provenance
The following attestation bundles were made for zbook-0.1.0-py3-none-any.whl:
Publisher:
release.yml on honglu2875/zbook
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
zbook-0.1.0-py3-none-any.whl -
Subject digest:
98ecbdd6b9067c58569c4b77b9bd25a4e888a5b0e5189947544e2b4cf6092853 - Sigstore transparency entry: 2568504901
- Sigstore integration time:
-
Permalink:
honglu2875/zbook@5746b80ba7cda9ae68d5340d6b699acb87dda2b3 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/honglu2875
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@5746b80ba7cda9ae68d5340d6b699acb87dda2b3 -
Trigger Event:
push
-
Statement type: