---
name: pcb-design
description: Design and generate complete PCB circuit boards using tscircuit (React/TypeScript). Use this skill whenever the user asks to create a PCB, circuit board, schematic, breakout board, Arduino/ESP32 shield, sensor module, or any electronics hardware project. Also trigger when the user mentions tscircuit, KiCad export, Gerber files, or wants to go from an idea to a manufacturable board. Even casual requests like "make me a board for..." or "I need a PCB that..." should trigger this skill. Covers component selection, placement, routing, and export to fabrication files.
---

# PCB Design Skill — tscircuit

Generate complete, routable PCB designs from high-level user descriptions using tscircuit, an open-source React/TypeScript electronics toolchain.

## When to Use

- User asks to design a PCB, circuit board, or electronic module
- User wants a breakout board, shield, sensor module, or dev board
- User mentions tscircuit, KiCad, Gerber, or fabrication files
- User describes a circuit functionally ("I need something that reads temperature and displays it")
- User asks to modify or iterate on an existing tscircuit design

## Philosophy

The user is likely an EE or maker who wants to go from idea to board fast. The goal is to produce a **complete, working tscircuit project** — not just a snippet. That means:

1. **Correct schematic connectivity** — every pin that needs a connection gets one
2. **Proper component selection** — realistic footprints, appropriate values, decoupling caps
3. **Thoughtful placement** — components positioned with `pcbX`/`pcbY` so the autorouter succeeds
4. **Manufacturable output** — the design should export to Gerbers and be orderable

## Workflow

### Step 1: Research Reference Designs

**Before writing any circuit, research the manufacturer's recommended minimum viable circuit for every key IC.** Do not guess component values — extract them from official sources.

For each core IC in the design:

1. **Find the manufacturer's hardware design guide** — most MCU vendors publish one (e.g., Raspberry Pi's "Hardware Design with RP2350", Espressif's "ESP32 Hardware Design Guidelines", ST's "Getting Started with STM32" app notes)
2. **Download official reference design files** — many manufacturers provide KiCad/Altium/Eagle files for their minimal/evaluation boards (e.g., Raspberry Pi publishes Minimal-KiCAD.zip with exact component values)
3. **Read the dev board schematic** — the manufacturer's evaluation board (e.g., Pico 2, ESP32-DevKitC, Nucleo) is the gold standard for "known working circuit"
4. **Extract exact component values** — capacitor values, inductor specs, resistor values, crystal load caps, and part numbers all come from these sources
5. **Cross-reference with community designs** — Adafruit, SparkFun, and other open-source boards validate the manufacturer's recommendations

**What to extract for each IC:**
- Power supply requirements (all voltage domains, current draw)
- Decoupling capacitor values and placement (per-pin requirements)
- Internal regulator/SMPS external component requirements (inductors, feedback resistors, filter networks)
- Clock/oscillator circuit (crystal frequency, load cap calculation, damping resistors)
- Reset and boot mode circuits
- Any mandatory pull-ups/pull-downs
- Recommended part numbers for critical components (inductors, crystals, flash)

**Where to search:**
- `datasheets.raspberrypi.com` — RP2040/RP2350 family
- `espressif.com/documentation` — ESP32 family
- `st.com/resource` — STM32 family
- `ti.com` — TI MCUs and power ICs
- Manufacturer GitHub repos for KiCad/design files
- Web search: "[chip] hardware design guide", "[chip] minimal circuit schematic", "[dev board] schematic PDF"

Focus on the components that make the chip actually function — power, clock, flash, reset. Don't worry about connectors, LEDs, or application-specific peripherals until the core circuit is solid.

### Step 2: Write Design Intent (.pdi)

Before writing any EDA-specific code, create a **design intent file** (`design-intent.pdi`) in the project folder. This is a structured, tool-agnostic representation that captures every component, its pin-level associations, and spatial grouping.

**See full format spec:** `references/design-intent-format.md`

**The .pdi file must specify:**
1. **Every power pin** of the main IC with its net assignment
2. **Every decoupling cap** tied to the specific pin it serves (not just "IOVDD" — say "decouples U1.pin22 (IOVDD)")
3. **Functional groups** with `near U1.pin##..##` placement constraints
4. **Every connection** — which pin connects to which component
5. **A verification checklist** at the bottom confirming completeness

**Structure:**
```pdi
board <width> x <height>

U1: <part> <package> @ center
  pin## (FUNCTION) → net.<name>
  ...

# Per-pin decoupling
C##: <value> <footprint>  decouples U1.pin## (<function>)

# Spatial groups
group <name> near U1.pin##..## {
  <ref>: <value> <footprint>  <connection_spec>
}
```

**Key connection specs:**
- `decouples <pin_ref>` — bypass cap on a power pin
- `from <pin/net> to <pin/net>` — component in a signal path
- `between <net> and GND` — component across power and ground
- `in_series from <pin> to <pin>` — series insertion (e.g., damping resistor)

**After writing, verify:**
- [ ] Every power pin has a decoupling cap or is documented as shared
- [ ] Every IC has power + decoupling accounted for
- [ ] Every group has a `near` clause for placement
- [ ] Total BOM count matches expectation
- [ ] All values sourced from reference design (Step 1)

**Then visualize** by generating an interactive viewer (PCB layout + schematic as HTML in AHDV) so the user can review the design before any EDA code is written.

### Step 3: Understand the Full Design

From the user's request and your reference design research, determine:
- **Core ICs** — microcontroller, sensors, drivers, regulators
- **Interfaces** — USB, I2C, SPI, UART, GPIO headers
- **Power** — voltage rails, regulation needs, battery vs USB power
- **Form factor** — board dimensions, mounting holes, connector placement
- **Constraints** — must-have features, pin assignments, specific parts

If the user's request is ambiguous, make reasonable EE decisions and state your assumptions clearly. Don't over-ask — design something solid and let the user iterate.

### Step 4: Set Up the Project

Scaffold a complete tscircuit project using the template script. This creates all config files, dependencies, and VS Code integration:

```bash
PROJECT_NAME="esp32-bme280-board"  # descriptive kebab-case name
bash /mnt/skills/user/pcb-design/scripts/scaffold.sh /home/claude/$PROJECT_NAME $PROJECT_NAME
```

This generates:
```html
<project-name>/
  .gitignore
  .npmrc                    ← points @tsci scope to tscircuit registry
  bunfig.toml               ← disables lockfile
  package.json              ← scripts: dev, build, start (tsci dev -p 3024)
  tscircuit.config.json     ← entrypoint config
  tsconfig.json             ← TypeScript config with JSX support
  index.tsx                 ← placeholder (you'll replace this)
  .vscode/
    settings.json           ← disables auto-detection noise
    tasks.json              ← "Start Dev Server", "Update Dependencies" tasks
```

After scaffolding, immediately run `bun update --latest` (the script does this automatically) to ensure all tscircuit dependencies are at the latest version.

Then replace `index.tsx` with the actual circuit design.

### Step 5: Design the Circuit

Read `references/tscircuit-elements.md` for the full element reference, and `references/common-circuits.md` for design pattern examples. Key principles:

**Every design needs:**
- A `<board>` root element with explicit `width` and `height`
- Named components following standard EE refdes conventions
- Explicit `pcbX`/`pcbY` placement for all components
- `<trace>` elements connecting all required pins
- Decoupling capacitors near every IC power pin (100nF ceramic, 0402 or 0603)
- Pull-up/pull-down resistors where the datasheet or protocol requires them (e.g., I2C needs pull-ups)

**Component naming conventions:**
- U1, U2... for ICs
- R1, R2... for resistors
- C1, C2... for capacitors
- L1, L2... for inductors
- D1, D2... for diodes/LEDs
- J1, J2... for connectors/headers
- SW1, SW2... for switches
- Q1, Q2... for transistors

**Placement strategy:**
- Place the main IC at or near center (0, 0)
- Group related components near their IC
- Keep decoupling caps within 2-3mm of their IC's power pins
- Place connectors at board edges
- Leave ~2mm clearance from board edges
- Space components enough for the autorouter (minimum ~2mm between unrelated parts)

### Step 6: Deliver to User

Create a complete, self-contained project folder and present it. The user should be able to download the folder, run `bun update --latest && bun run start`, and see their board.

1. **Copy source files only** from `/home/claude/<project-name>/` to `/mnt/user-data/outputs/<project-name>/` — **never copy `node_modules/`** (it's 400MB+ and the user will run `bun update --latest` themselves)
2. **Write a `README.md`** in that folder containing:
   - Project name and one-line description
   - Design assumptions (voltages, interfaces, component choices)
   - Bill of Materials summary (component, value, footprint, quantity)
   - How to run: `bun update --latest`, then `bun run start`
   - Pin mapping / net summary for the user's firmware
   - Any known limitations or things the user should verify
3. **Use `present_files`** to share the key output files (index.tsx, README.md) with the user

Example delivery commands:
```bash
# Create output directory with .vscode subfolder
mkdir -p /mnt/user-data/outputs/esp32-bme280-board/.vscode

# Copy source files ONLY — never use cp -r on the project root (leaks node_modules)
for f in package.json tsconfig.json tscircuit.config.json bunfig.toml .npmrc .gitignore index.tsx README.md; do
  cp "/home/claude/esp32-bme280-board/$f" "/mnt/user-data/outputs/esp32-bme280-board/$f"
done
cp /home/claude/esp32-bme280-board/.vscode/*.json /mnt/user-data/outputs/esp32-bme280-board/.vscode/
```

The output folder will contain:
```text
/mnt/user-data/outputs/esp32-bme280-board/
  .gitignore
  .npmrc
  bunfig.toml
  package.json
  tscircuit.config.json
  tsconfig.json
  index.tsx          ← the actual circuit design
  README.md          ← design notes, BOM, instructions
  .vscode/
    settings.json
    tasks.json
```

**⚠️ Never include `node_modules/` in the output.** The user installs dependencies themselves with `bun update --latest`.

## tscircuit Quick Reference

### Core Elements

```tsx
// Board — root container, everything goes inside
<board width="50mm" height="40mm">
  {/* components and traces */}
</board>

// Resistor — non-polar, 2 pins: pin1/pin2 (aliases: pos/neg)
<resistor name="R1" resistance="10k" footprint="0402" pcbX={5} pcbY={3} />

// Capacitor — 2 pins: pin1/pin2 (aliases: pos/neg for polarized)
<capacitor name="C1" capacitance="100nF" footprint="0402" pcbX={2} pcbY={1} />

// LED — 2 pins: anode(pos)/cathode(neg)
<led name="LED1" footprint="0603" color="green" pcbX={10} pcbY={0} />

// Diode
<diode name="D1" footprint="sot23" pcbX={0} pcbY={5} />

// Generic IC via <chip> — the workhorse element
<chip
  name="U1"
  footprint="soic8"
  pinLabels={{
    pin1: "VCC", pin2: "OUT", pin3: "NC", pin4: "GND",
    pin5: "TRG", pin6: "THR", pin7: "DIS", pin8: "RST"
  }}
  connections={{          // shorthand for traces
    VCC: "net.VCC",
    GND: "net.GND",
  }}
  pcbX={0} pcbY={0}
/>

// Pin header — for GPIO breakout, programming, etc.
<pinheader name="J1" pinCount={6} pitch="2.54mm" pcbX={-20} pcbY={0} />

// Traces — connect pins together
<trace from=".R1 > .pin1" to=".U1 > .OUT" />       // direct pin-to-pin
<trace from=".C1 > .pin1" to="net.GND" />            // connect to named net
```

### Footprint Strings

| Type | Examples |
|------|---------|
| Passives | `0402`, `0603`, `0805`, `1206` |
| SOIC | `soic8`, `soic14`, `soic16`, `soic16_w7mm_p0.8mm` |
| QFP/TQFP | `qfp32`, `qfp48`, `tqfp32`, `tqfp48` |
| QFN | `qfn20`, `qfn24`, `qfn32`, `qfn24_w6_h6_p0.8mm` |
| BGA | `bga9`, `bga16`, `bga16_p2mm` |
| TSSOP/SSOP | `tssop8`, `tssop16`, `tssop20`, `ssop8` |
| SOT | `sot23`, `sot23_5`, `sot223` |
| DIP | `dip8`, `dip14`, `dip16`, `dip8_wide` |
| Pin rows | `pinrow4`, `pinrow8`, `pinrow10` |
| TO packages | `to92`, `to220` |
| Stampboard | `stampboard` (for module-style packages) |

### Trace Addressing

```text
".ComponentName > .pinLabel"   — by label (preferred when pinLabels are set)
".ComponentName > .pin1"       — by pin number
"net.VCC"                      — named power net
"net.GND"                      — ground net
"net.SDA"                      — named signal net
```

### Reusable Subcomponents

```tsx
import type { CommonLayoutProps } from "tscircuit"

interface RegProps extends CommonLayoutProps {
  name: string
}

export const AMS1117_3V3 = (props: RegProps) => (
  <chip
    footprint="sot223"
    pinLabels={{ pin1: "GND", pin2: "VOUT", pin3: "VIN" }}
    {...props}
  />
)
```

### Board Options

```tsx
<board
  width="50mm"
  height="40mm"
  layers={4}                    // 2 (default) or 4 layer stackup
  defaultTraceWidth="0.25mm"
  minTraceWidth="0.15mm"
  autorouter="auto-cloud"       // use for >50 traces
  borderRadius="2mm"            // rounded corners
>
```

## Critical Design Rules

1. **Always research before designing.** Every IC has specific power supply requirements, decoupling needs, and support circuitry. The datasheet and manufacturer's reference design are the source of truth — not generic rules of thumb. Download official design files when available.

2. **Use datasheet-specified decoupling.** The generic "100nF per VCC pin" is a starting point, but many ICs specify exact values per pin. For example, RP2350B needs 100nF per IOVDD pin, but 4.7µF for DVDD and specific RC filtering on VREG_AVDD. Always check the datasheet.

3. **Internal regulators need exact external components.** Many modern MCUs (RP2350, STM32, nRF52) have internal switching regulators that require specific inductors, capacitors, and feedback networks. These values are NOT interchangeable — use exactly what the datasheet specifies (e.g., RP2350 needs a 3.3µH polarized inductor with ≤250mΩ DCR).

4. **I2C buses need pull-ups.** Add 4.7kΩ resistors on SDA and SCL to VCC. Lower values (2.2k) for faster buses or longer traces.

5. **Use net-based traces for power.** Connect all power pins via `net.VCC` / `net.GND` rather than chaining direct traces. This lets the autorouter find optimal paths.

6. **Size the board generously for simple designs.** It's easier to shrink a working board than to debug a cramped one. Start with plenty of room.

7. **Reset and enable pins matter.** Check the datasheet for recommended pull-up values — they vary by chip (e.g., RP2350 uses 1kΩ on RUN, ESP32 uses 10kΩ on EN with an RC filter).

8. **Crystal/oscillator placement.** Keep crystals within 5mm of the MCU, with load capacitors placed symmetrically. Always calculate load cap values from the crystal's specified load capacitance: C_load = 2 × (C_crystal_load - C_stray). Include a series damping resistor if the datasheet recommends one (e.g., RP2350 uses 1kΩ).

9. **USB connector placement.** Put USB connectors at the board edge with the receptacle flush or slightly overhanging. USB D+/D- lines may need series resistors (e.g., RP2350 uses 27Ω).

10. **Module footprints.** ESP32-WROOM, ESP32-S3, and similar WiFi/BLE modules use a castellated pad footprint. In tscircuit, use `stampboard` as a working placeholder — it gives you the right pin count and general shape. For production, import the exact footprint from the tscircuit registry (`@tsci/username.esp32-wroom`) or use a KiCad footprint (`footprint="kicad:RF_Module/ESP32-WROOM-32"`). Note this clearly in the README as a pre-production step.

## Project Specific Instructions

tscircuit uses `bun`, so the correct command to run the dev server is `bun run start`, **not** `npm run dev` or `npm start`.

**Critical:** Always run `bun update --latest` immediately after scaffolding a project. This ensures all tscircuit packages are at the latest version. The scaffold script does this automatically, but if it fails (e.g., in a restricted network environment), remind the user to run it manually.

When writing README files or explaining next steps to the user, always use:

```bash
# First time setup (in the project directory)
bun update --latest    # update all tscircuit dependencies to latest

# Launch dev server with live PCB/schematic/3D preview
bun run start
```

Other useful tscircuit CLI commands:
```bash
tsci export gerber     # export Gerber fabrication files
tsci export bom        # export Bill of Materials
tsci export pnp        # export Pick-and-Place file
```

## Reference Files

- `references/tscircuit-elements.md` — Detailed element API reference (read for unfamiliar elements)
- `references/common-circuits.md` — Complete design patterns: power, MCU, sensors, USB, LEDs
