Ryan Malloy 00fa420743 Add iframe auto-resize via postMessage
Embeds now report content height to the parent frame using a
ResizeObserver on document.body. The EmbedDialog snippet includes
a listener script that adjusts the iframe height on each resize
event. Documented the spicebook-resize protocol in llms.txt.
2026-03-07 23:45:10 -07:00

SpiceBook

A notebook interface for SPICE circuit simulation.

Write the narrative. Run the simulation. See the waveform. All in one document.


SpiceBook notebook showing RC lowpass filter with Bode plot and step response waveforms

What is this?

SpiceBook is a notebook for circuit engineers. Markdown cells for explanation, SPICE cells for simulation, waveform plots for results -- interleaved in a single document you can re-run, share, and version control.

Think "Jupyter for circuits" except it actually understands SPICE. The editor highlights your .tran and .ac commands. The waveform viewer knows about dB and degrees. Engineering notation on the axes reads 1.59 kHz, not 1591.549.

Nothing else does this. PySpice needs you to write Python. CircuitLab is closed-source and schematic-only. Multisim Live is shutting down. The browser-based ngspice wrappers give you one netlist and one plot -- no narrative, no interleaving, no notebook.

SpiceBook lets you write a document that says: "here's why this filter works, here's the AC analysis proving it, here's the step response confirming the time constant" -- and every claim is backed by a live, re-runnable simulation.

Features

  • Markdown cells with rendered preview -- headings, bold, lists, inline math notation

  • SPICE cells with CodeMirror 6 and custom syntax highlighting:

    • Dot commands (.tran, .ac, .dc, .model, .param, .subckt, ...)
    • Component prefixes (R, C, L, V, I, M, Q, D, X)
    • Engineering notation (1k, 10u, 3.3meg, 100p)
    • Comments (* and ;), brace expressions ({10k*(1-x)})
  • Waveform viewer built on uPlot (~50KB, fast):

    • Multi-trace overlay with color-coded legend
    • Stacked Bode plots (magnitude dB + phase degrees) for AC analysis
    • Time-domain plots for transient analysis
    • Log-scale frequency axis, engineering-notation labels
    • Click-drag zoom, scroll to pan
  • ngspice backend -- subprocess execution with binary .raw file parsing

  • Notebook operations -- create, open, edit, save, delete, reorder cells, run individually or all at once

  • Color-coded resistor schematics -- zigzag symbols colored with standard 4-band resistor color codes. A 10kΩ resistor renders Brown-Black-Orange-Gold directly on the schematic symbol, bridging the gap between physical components and abstract schematics. Falls back to standard monochrome for parametric or out-of-range values.

  • Keyboard shortcuts -- Ctrl+S save, Shift+Enter run cell

  • Clean URLs -- /notebook/rc-lowpass-filter via Astro dynamic routes

  • 15 example notebooks included:

    Fundamentals:

    • RC Lowpass Filter Analysis (AC + transient)
    • Voltage Divider (DC operating point + sweep)
    • Common Emitter Amplifier (AC + transient with BJT model)
    • RC Step Response, RLC Bandpass Filter, Diode Rectifier, LED I-V Curve, Inverting Op-Amp, CMOS Inverter

    Advanced (multi-cell, real-world circuits):

    • Synchronous Buck Converter -- 12V-to-3.3V switching regulator with startup and steady-state detail
    • Class AB Push-Pull Audio Amplifier -- frequency response, clean output, and overdrive clipping
    • AM Radio Receiver -- envelope detection with carrier and audio waveforms
    • Dickson Charge Pump -- voltage multiplication under light and heavy loads
    • Transmission Line Signal Integrity -- unterminated ringing vs series-terminated clean signals
    • 4th-Order Sallen-Key Butterworth Filter -- active filter vs passive RC comparison
    • Colpitts RF Oscillator -- ~1 MHz oscillation startup and steady-state

Quick Start

Prerequisites

  • ngspice -- the simulation engine
    • Arch: sudo pacman -S ngspice
    • Debian/Ubuntu: sudo apt install ngspice
    • macOS: brew install ngspice
  • Python 3.12+ with uv
  • Node.js 20+

Local Development (no Docker)

# Clone
cd spicebook

# Backend
cd backend
uv sync
uv run uvicorn spicebook.main:app --host 0.0.0.0 --port 8099 --reload

# Frontend (separate terminal)
cd frontend
npm install
npx astro dev --host 0.0.0.0 --port 4322

Open http://localhost:4322

Docker (Development)

make dev

Frontend at http://localhost:4321, backend at http://localhost:8099, API docs at http://localhost:8099/docs.

Docker (Production)

make prod

Production mode runs behind Caddy with TLS via caddy-docker-proxy. Set SPICEBOOK_DOMAIN in .env.

Makefile Targets

Target What it does
make dev Build and start dev containers with hot-reload
make prod Build and start production containers
make down Stop all containers
make logs Tail container logs
make clean Remove containers, volumes, and build artifacts
make backend-shell Shell into the backend container
make help List all targets

Project Structure

spicebook/
├── frontend/                # Astro 5 + React 19
│   ├── src/
│   │   ├── pages/           # Astro routes (index, /notebook/[id])
│   │   ├── components/
│   │   │   ├── notebook/    # Editor, cells, output viewers, toolbar
│   │   │   └── ui/          # Button, Badge, Dropdown (shadcn/ui)
│   │   ├── lib/
│   │   │   ├── spice-language.ts   # CodeMirror SPICE mode
│   │   │   ├── waveform-utils.ts   # Engineering notation formatter
│   │   │   ├── notebook-store.ts   # Zustand state
│   │   │   ├── api.ts              # Backend client
│   │   │   └── types.ts            # TypeScript types
│   │   └── styles/globals.css
│   └── astro.config.mjs
├── backend/                 # FastAPI + ngspice
│   ├── src/spicebook/
│   │   ├── main.py          # App factory, health check
│   │   ├── config.py        # Settings from environment
│   │   ├── engine/          # SPICE engine abstraction
│   │   │   ├── base.py      # Abstract base class
│   │   │   ├── ngspice.py   # ngspice subprocess + .raw parser
│   │   │   ├── schematic.py # Netlist → SVG schematic (SchemDraw)
│   │   │   └── resistor_colors.py  # Color-coded zigzag resistors
│   │   ├── models/          # Pydantic schemas
│   │   │   ├── notebook.py  # Notebook, Cell, CellOutput
│   │   │   └── simulation.py
│   │   ├── routers/         # API endpoints
│   │   │   ├── notebooks.py # CRUD
│   │   │   ├── simulation.py # Run cells
│   │   │   └── waveforms.py # Waveform data
│   │   └── storage/
│   │       └── filesystem.py # .spicebook file I/O
│   ├── tests/
│   └── pyproject.toml
├── notebooks/
│   ├── examples/            # Shipped example notebooks
│   └── user/                # User-created (gitignored)
├── docker-compose.yml       # Base services
├── docker-compose.dev.yml   # Dev overrides (hot-reload, port mapping)
├── docker-compose.prod.yml  # Prod overrides (Caddy, no ports exposed)
├── Makefile
└── .env

.spicebook File Format

Notebooks are JSON files with a .spicebook extension. Git-friendly, outputs persisted inline.

{
  "spicebook_version": "2026-02-13",
  "metadata": {
    "title": "RC Lowpass Filter Analysis",
    "engine": "ngspice",
    "tags": ["filter", "passive"]
  },
  "cells": [
    {
      "id": "cell-001",
      "type": "markdown",
      "source": "# My Circuit\nExplanation goes here.",
      "outputs": []
    },
    {
      "id": "cell-002",
      "type": "spice",
      "source": "V1 in 0 AC 1\nR1 in out 1k\nC1 out 0 100n\n.ac dec 100 1 10meg\n.end",
      "outputs": [
        {
          "output_type": "simulation_result",
          "data": { "success": true, "waveform": { "..." : "..." } },
          "timestamp": "2026-02-13T12:00:00Z"
        }
      ]
    }
  ]
}

Tech Stack

Layer Technology
Frontend framework Astro 5 (SSR, Node adapter)
Interactive islands React 19
Code editor CodeMirror 6 (custom SPICE language mode)
Waveform charts uPlot
State management Zustand
Styling Tailwind CSS 4
UI components shadcn/ui
Icons Lucide
Backend FastAPI
SPICE engine ngspice (subprocess)
Data validation Pydantic
Containerization Docker Compose
Reverse proxy Caddy (via caddy-docker-proxy)

API

The backend exposes a REST API. When running in dev mode, interactive docs are at http://localhost:8099/docs.

Key endpoints:

Method Path Description
GET /api/notebooks List all notebooks
GET /api/notebooks/{id} Get a notebook
POST /api/notebooks Create a notebook
PUT /api/notebooks/{id} Update a notebook
DELETE /api/notebooks/{id} Delete a notebook
POST /api/notebooks/{id}/cells/{cell_id}/run Run a SPICE cell
POST /api/simulate Run a standalone simulation
GET /health Health check

Configuration

All configuration is via environment variables (.env file). See .env for the full list.

Variable Default Description
ENVIRONMENT dev dev or prod
BACKEND_PORT 8099 Backend port (dev only)
FRONTEND_PORT 4321 Frontend port (dev only)
NGSPICE_PATH /usr/bin/ngspice Path to ngspice binary
NOTEBOOK_DIR /app/notebooks Notebook storage path
SPICEBOOK_DOMAIN -- Domain for production (Caddy TLS)
VITE_HMR_HOST -- Set when behind reverse proxy

Roadmap

Phase 2 -- Core Features

  • Python cells with sandboxed execution and cross-cell data access
  • LTspice engine integration (via mcltspice library)
  • Measurement cursors in waveform viewer
  • SVG/CSV export for waveforms
  • Signal analysis: FFT, THD, RMS, bandwidth
  • KaTeX math rendering in markdown cells

Phase 3 -- Advanced

  • Schematic cells (SchemDraw backend rendering)
  • Auto-schematic generation from netlist
  • WebSocket progress for long simulations
  • LTspice .asc file import

Phase 4 -- Polish

  • Interactive schematic editor (tscircuit integration)
  • Parameter sweeps with overlay plots
  • Monte Carlo analysis visualization
  • Template gallery

Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b my-feature
  3. Make changes and add tests
  4. Run the linter: cd backend && uv run ruff check .
  5. Run tests: cd backend && uv run pytest
  6. Submit a pull request

Versioning

SpiceBook uses date-based versioning (YYYY.MM.DD). The current version is 2026.02.13.


Built by Ryan Malloy

Description
Notebook interface for SPICE circuit simulation
Readme 184 MiB
Languages
TypeScript 35.8%
Python 25.1%
CSS 11.7%
Astro 10.6%
Shell 8%
Other 8.8%