Inspiration

Designing a PCB is one of the most gatekept things in engineering. Even the simplest "blink an LED on a button press" board requires you to learn KiCad, pick footprints, place parts, route copper, generate Gerbers, set up an order at JLCPCB, write the firmware, and pray you got the polarity right. The skill ceiling is high enough that most people with a great hardware idea (students, makers, founders) never even start.

Meanwhile, the rest of software has had its "ChatGPT moment." You can vibe-code a webapp in a single prompt. So I asked: why not boards?

Boardsmith is my answer. Vibe coding, but it makes circuit boards. And exports them.

What it does

You type or paste a photo of a hand-drawn schematic, or both, whichever you want:

"An ESP32 board that reads a DHT22 temperature sensor and lights up an LED when it's above 25°C, USB-C powered."

Boardsmith returns, in about a minute:

  • A live schematic rendered in the browser (schemdraw SVG).
  • A KiCad 10 .kicad_sch file with auto-sized A4→A0 paper, three-column layout (power / logic / IO), and clean labeled net stubs you can open and edit.
  • A 2D PCB layout with placement and routing.
  • A 3D board render in Three.js, lit and rotatable.
  • A bill of materials with LCSC part numbers, quantities, and a live JLCPCB cost calculator (1–500 boards, with a slider) that breaks out parts + fab + SMT setup + per-joint placement + shipping.
  • A pick-and-place CSV for SMT assembly.
  • An RS-274X Gerber bundle ready to upload to JLCPCB.
  • A starter Arduino .ino sketch that compiles, with the actual pin assignments from your schematic.
  • A one-click "Simulate" button that exports the design to Falstad's circuitjs1 and runs it live in the browser — animated current flow, LEDs that actually light up, push buttons you can click.

Plus: persistent project history, refinement chains ("now add a buzzer"), Google sign-in, public /p/<short-id> share links for portfolio demos, and a design-decisions panel where the LLM explains why it picked the parts it did.

The whole thing ships as one zip. You upload it to JLCPCB. Five days later boards arrive at your door.

How I built it

Backend — Python 3.11 + FastAPI, streaming an 8-stage pipeline over Server-Sent Events: parse → schematic → firmware → bom → pcb_layout → routing → 3d → gerber

  • Gemini 2.5 Pro for both natural-language → CircuitDesign JSON parsing and image → JSON via Gemini Vision. Two prompt modes: "component-level" (when the user names parts) and "intent-level" (when they describe a goal — Boardsmith picks the MCU, power chain, and pull-ups).
  • schemdraw + a custom SVG renderer for the schematic preview.
  • A hand-built KiCad 10 .kicad_sch writer that emits proper lib_symbols, snapped placements on a 1.27 mm grid, and global/local net labels — KiCad opens it natively, no DRC errors.
  • A grid-based router for the PCB layout with copper pours and via stitching.
  • A custom Gerber writer (RS-274X + Excellon drill) — no third-party EDA dependency.
  • JLCPCB pricing model mirroring their published formula: tiered fab cost, $8 SMT setup, $0.0017/joint placement, scrap buffer, stencil, shipping.
  • Falstad exporter that converts a CircuitDesign to circuitjs1's element format, lzstring-compressed into a shareable URL.
  • Supabase for Google OAuth + Postgres persistence (asyncpg), with JWKS-based JWT verification supporting both legacy HS256 and modern asymmetric ES256/RS256 signing keys.

Frontend — React + Vite + TypeScript + Tailwind v4 + Three.js. Persistent three-pane IDE layout (Jobs sidebar / Pipeline progress / Viewer tabs), collapsible columns, Supabase auth, and a public viewer route for shared links.

Deployment — Railway, frontend and backend as separate services.

Challenges I ran into

  • Supabase migrated to asymmetric JWT signing keys mid-build. My backend was verifying HS256 tokens; suddenly every request returned {"detail":"invalid token: alg not allowed"}. Fix: rewrite auth.py to fetch the JWKS endpoint and verify ES256/RS256 dynamically.
  • Falstad's SwitchElm has inverted semantics. position=0 means closed, position=1 means open — the opposite of what every UI implies. My buttons were "always pressed" and the LEDs short-circuited at rest. The fix took digging into the circuitjs1 Java source.
  • Tailwind v4's JIT purge dropped our group-hover:opacity-100 classes in production but kept them in dev. The delete-job button rendered invisibly on Railway but worked perfectly on localhost. Fix: switch to useState + onMouseEnter for the hover state.
  • KiCad spacing errors on big designs. My writer hardcoded A4 paper. A user dropped in an STM32 + dual sensor + 8-LED design (30 components) and watched half of them run off the page. Fix: pre-compute per-column vertical demand, pick the smallest standard paper (A4 → A0) that fits, and wrap to a sub-column if even A0 isn't enough.
  • Gemini's "over-design" tendency. Ask for a "simple sensor," get an MCU you didn't want. Fix: a system prompt that distinguishes "component-level" prompts (build exactly what I said) from "intent-level" goals (build something minimal that achieves this), and a separate "design decisions" channel where the LLM explains its trade-offs.
  • Supabase's IPv6-only direct URL. Local dev couldn't connect. The session-mode pooler URL is IPv4 — undocumented gotcha.
  • PowerShell doesn't have heredocs, so committing a multi-line message via git commit -m "$(cat <<EOF...)" blew up. I ended up writing commit messages to a temp file and using git commit -F.

Accomplishments that I'm proud of

  • It actually produces manufacturable boards. Not mockups, not screenshots, but real Gerbers that JLCPCB accepts and fabricates.
  • Multimodal input. Drop a photo of a napkin sketch into the prompt box and Gemini Vision turns it into a routed PCB. It feels like magic the first time.
  • Live cost calculator. Slide from 1 to 500 boards and watch the parts × scrap-buffer + fab tier + per-joint SMT cost update in real time. Judges have been asking the right question — "how much does this actually cost?" — and I have the answer.
  • One-click simulation. Falstad runs your circuit live in the browser with animated current flow, before you've spent a cent on parts.
  • Auto-generated firmware. The Arduino .ino sketch uses the actual pins from the schematic. You flash it and the LED blinks on the first try.
  • Refinement chains. "Now add a buzzer that beeps when the temp is high" — Boardsmith forks the previous design, regenerates, preserves lineage.
  • Persistent, shareable, auth-gated, beautiful. The whole product surface — sidebar, viewer tabs, design notes, share links — feels like a real tool, not a demo.

What I learned

  • LLMs are great at intent, terrible at geometry. Gemini nails "what should this circuit do" but happily places overlapping components if you let it. The right architecture is: LLM for the netlist, deterministic code for the layout.
  • A good prompt is a system, not a sentence. Splitting parsing into "component-level vs intent-level" modes was a 10x quality jump for natural-language input.
  • Hardware tooling has decades of buried assumptions. KiCad's grid is 1.27 mm because of imperial inheritance. Falstad's switch is inverted because of a 2008 Java decision. Gerber is a 1980s plotter format we still use. You have to learn the history to ship the future.
  • Auth and persistence aren't features, they're prerequisites. Nobody believes a demo until they can sign in, leave, come back, and find their work.
  • Streaming UX is everything. An 8-stage pipeline that takes 60 seconds feels instant when each stage flashes a "complete" badge as it lands.

What's next for Boardsmith

  • Closed-loop DRC and ERC. Currently it generates clean designs, next I want to verify them with real design-rule checks before shipping the Gerbers.
  • Multi-board projects. A controller board + a sensor board + a flexible interconnect, all from one prompt.
  • In-browser SPICE. Falstad is fast and visual but limited. I want full SPICE for the analog users, with ngspice running in WASM.
  • Component-library expansion. ESP32-S3, Raspberry Pi Pico, BLE modules, motor drivers, op-amps. Every part we add unlocks a new class of projects.
  • Direct JLCPCB ordering. Today you download the zip and upload it to JLCPCB. Tomorrow: one button, one Stripe checkout, boards at your door.
  • A standalone hardware copilot. Once the generator is solid, I want the editor: select a trace, ask "make this differential pair," watch it route.

Built With

Share this project:

Updates