Ground Truth
A drag-and-drop breadboard playground for learning electronics. Build a circuit on a virtual breadboard, ngspice simulates it live, and a Gemini lab partner explains what's going on and suggests what to try next.
The simulator supplies the numbers; Gemini supplies the teaching. Every voltage and current in the app comes from ngspice, and Gemini's replies are labeled as AI output.

Demo video: [https://youtu.be/10aBEzMMXms?si=x15zPVuf3NLDpoNG) (under 2 minutes: find a fault, fix it, build an LED circuit from scratch, switch a transistor, see the schematic).
What it does
Spot the mistake. The rule checker reads the simulated numbers and flags faults on the board. Here, the resistor ends in row 14 but the LED's anode sits in row 15, so no current flows. A ghost marks where the leg should go, and apply fix moves it.

Watch it work. Live readouts update on every edit. In the transistor switch, select SW1 and hold Space: a small base current through R2 switches the LED current through Q1.

See the schematic. The schematic is generated from the same circuit, stacked by simulated voltage, with selection synced to the breadboard.

Start from scratch. Drag a battery, resistor, LED and wires from the parts bin. Hover a part to see its legs, default value and shortcut key.

Ask the lab partner. "review", "why isn't it working?", "explain" and "ideas" send the circuit, nets, simulation results and rule findings to Gemini. "build one for me" asks Gemini to propose a circuit that loads onto the board, where ngspice simulates it like any other.
How it works
- Editor. Parts snap onto breadboard holes. Holes a–e and f–j in the same row are connected, plus four power rails, just like a real breadboard.
- Simulation. Every edit rebuilds a SPICE netlist and runs
ngspiceon a background thread. Zero-volt sources act as ammeters on each leg. Circuits with capacitors run a live transient simulation, plotted on the SCOPE panel. - Rule checks. A checker reads the simulated numbers and reports faults in plain language: an LED that draws no current, an LED plugged in backwards, too much current with no resistor, a shorted battery, a leg in the wrong row. Faults it can fix get an apply fix button.
- Lab partner. Gemini receives the circuit, the nets, the ngspice results, the rule findings and the netlist, and replies with structured JSON: a message, issues tied to part ids (hover one to highlight the parts), and ideas to try.
Running it
You need Rust and ngspice on your PATH (brew install ngspice on macOS, sudo apt install ngspice on Debian/Ubuntu).
cp .env.example .env # then add your GEMINI_API_KEY
cargo run
Open examples for ready-made circuits (LED, transistor switch, pot dimmer, night light, fading LED, blinker, voltage divider, two LEDs in parallel, and broken ones to debug: wrong row, reversed LED, no resistor, battery short), or pass one on the command line: cargo run -- circuits/pot_dimmer.json --split.
The app works without a Gemini key; only the lab partner is disabled. GEMINI_MODEL and NGSPICE_PATH in .env are optional.
Tests
cargo test # needs ngspice for the simulation checks
cargo test gemini_live -- --ignored --nocapture # live Gemini call, needs GEMINI_API_KEY
Every example in circuits/ has an expect block that the tests check against the simulation, so the examples double as regression tests.
Layout
src/circuit.rs: holes, parts, circuits, SI value parsingsrc/sim/: SPICE netlist builder, ngspice runner, rule checkssrc/assistant.rs: Gemini lab partnersrc/ui/: breadboard editor, schematic, themesrc/app.rs: panels, undo/redo, save/opencircuits/: example circuits
What's next
- Probe a physical breadboard with an Arduino UNO Q and compare the real readings with the simulation.
- More parts, starting with the 555 timer.
- Talk to the lab partner by voice with the Gemini Live API.
Log in or sign up for Devpost to join the conversation.