skill
PCB design — tscircuit
UnreviewedDesign and generate complete PCB circuit boards using tscircuit (React/TypeScript). Use when the user asks to create a PCB, circuit board, schematic, breakout board, Arduino/ESP32 shield, sensor modul
{
"schema_version": 1,
"type": "skill",
"slug": "pcb-design",
"title": "PCB design — tscircuit",
"brief": "Design and generate complete PCB circuit boards using tscircuit (React/TypeScript). Use when the user asks to create a PCB, circuit board, schematic, breakout board, Arduino/ESP32 shield, sensor modul",
"version": "1.0.0",
"tags": [],
"license": "MIT",
"sample_prompts": [
{
"label": "Make a PCB",
"prompt": "Design a PCB for an ESP32 with a BME680"
},
{
"label": "Breakout board",
"prompt": "Make me a breakout for the VL53L8CX ToF sensor"
},
{
"label": "Functional spec",
"prompt": "I need a board that reads temperature and shows it on a screen"
},
{
"label": "Arduino shield",
"prompt": "Design an Arduino shield for stepper-motor control"
},
{
"label": "Export gerbers",
"prompt": "Export gerbers + BOM + CPL for this tscircuit project"
}
],
"source_path": "SKILL.md",
"readme": "---\nname: pcb-design\ndescription: 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.\n---\n\n# PCB Design Skill — tscircuit\n\nGenerate complete, routable PCB designs from high-level user descriptions using tscircuit, an open-source React/TypeScript electronics toolchain.\n\n## When to Use\n\n- User asks to design a PCB, circuit board, or electronic module\n- User wants a breakout board, shield, sensor module, or dev board\n- User mentions tscircuit, KiCad, Gerber, or fabrication files\n- User describes a circuit functionally (\"I need something that reads temperature and displays it\")\n- User asks to modify or iterate on an existing tscircuit design\n\n## Philosophy\n\nThe 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:\n\n1. **Correct schematic connectivity** — every pin that needs a connection gets one\n2. **Proper component selection** — realistic footprints, appropriate values, decoupling caps\n3. **Thoughtful placement** — components positioned with `pcbX`/`pcbY` so the autorouter succeeds\n4. **Manufacturable output** — the design should export to Gerbers and be orderable\n\n## Workflow\n\n### Step 1: Research Reference Designs\n\n**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.\n\nFor each core IC in the design:\n\n1. **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)\n2. **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)\n3. **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\"\n4. **Extract exact component values** — capacitor values, inductor specs, resistor values, crystal load caps, and part numbers all come from these sources\n5. **Cross-reference with community designs** — Adafruit, SparkFun, and other open-source boards validate the manufacturer's recommendations\n\n**What to extract for each IC:**\n- Power supply requirements (all voltage domains, current draw)\n- Decoupling capacitor values and placement (per-pin requirements)\n- Internal regulator/SMPS external component requirements (inductors, feedback resistors, filter networks)\n- Clock/oscillator circuit (crystal frequency, load cap calculation, damping resistors)\n- Reset and boot mode circuits\n- Any mandatory pull-ups/pull-downs\n- Recommended part numbers for critical components (inductors, crystals, flash)\n\n**Where to search:**\n- `datasheets.raspberrypi.com` — RP2040/RP2350 family\n- `espressif.com/documentation` — ESP32 family\n- `st.com/resource` — STM32 family\n- `ti.com` — TI MCUs and power ICs\n- Manufacturer GitHub repos for KiCad/design files\n- Web search: \"[chip] hardware design guide\", \"[chip] minimal circuit schematic\", \"[dev board] schematic PDF\"\n\nFocus 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.\n\n### Step 2: Write Design Intent (.pdi)\n\nBefore 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.\n\n**See full format spec:** `references/design-intent-format.md`\n\n**The .pdi file must specify:**\n1. **Every power pin** of the main IC with its net assignment\n2. **Every decoupling cap** tied to the specific pin it serves (not just \"IOVDD\" — say \"decouples U1.pin22 (IOVDD)\")\n3. **Functional groups** with `near U1.pin##..##` placement constraints\n4. **Every connection** — which pin connects to which component\n5. **A verification checklist** at the bottom confirming completeness\n\n**Structure:**\n```pdi\nboard <width> x <height>\n\nU1: <part> <package> @ center\n pin## (FUNCTION) → net.<name>\n ...\n\n# Per-pin decoupling\nC##: <value> <footprint> decouples U1.pin## (<function>)\n\n# Spatial groups\ngroup <name> near U1.pin##..## {\n <ref>: <value> <footprint> <connection_spec>\n}\n```\n\n**Key connection specs:**\n- `decouples <pin_ref>` — bypass cap on a power pin\n- `from <pin/net> to <pin/net>` — component in a signal path\n- `between <net> and GND` — component across power and ground\n- `in_series from <pin> to <pin>` — series insertion (e.g., damping resistor)\n\n**After writing, verify:**\n- [ ] Every power pin has a decoupling cap or is documented as shared\n- [ ] Every IC has power + decoupling accounted for\n- [ ] Every group has a `near` clause for placement\n- [ ] Total BOM count matches expectation\n- [ ] All values sourced from reference design (Step 1)\n\n**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.\n\n### Step 3: Understand the Full Design\n\nFrom the user's request and your reference design research, determine:\n- **Core ICs** — microcontroller, sensors, drivers, regulators\n- **Interfaces** — USB, I2C, SPI, UART, GPIO headers\n- **Power** — voltage rails, regulation needs, battery vs USB power\n- **Form factor** — board dimensions, mounting holes, connector placement\n- **Constraints** — must-have features, pin assignments, specific parts\n\nIf 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.\n\n### Step 4: Set Up the Project\n\nScaffold a complete tscircuit project using the template script. This creates all config files, dependencies, and VS Code integration:\n\n```bash\nPROJECT_NAME=\"esp32-bme280-board\" # descriptive kebab-case name\nbash /mnt/skills/user/pcb-design/scripts/scaffold.sh /home/claude/$PROJECT_NAME $PROJECT_NAME\n```\n\nThis generates:\n```html\n<project-name>/\n .gitignore\n .npmrc ← points @tsci scope to tscircuit registry\n bunfig.toml ← disables lockfile\n package.json ← scripts: dev, build, start (tsci dev -p 3024)\n tscircuit.config.json ← entrypoint config\n tsconfig.json ← TypeScript config with JSX support\n index.tsx ← placeholder (you'll replace this)\n .vscode/\n settings.json ← disables auto-detection noise\n tasks.json ← \"Start Dev Server\", \"Update Dependencies\" tasks\n```\n\nAfter scaffolding, immediately run `bun update --latest` (the script does this automatically) to ensure all tscircuit dependencies are at the latest version.\n\nThen replace `index.tsx` with the actual circuit design.\n\n### Step 5: Design the Circuit\n\nRead `references/tscircuit-elements.md` for the full element reference, and `references/common-circuits.md` for design pattern examples. Key principles:\n\n**Every design needs:**\n- A `<board>` root element with explicit `width` and `height`\n- Named components following standard EE refdes conventions\n- Explicit `pcbX`/`pcbY` placement for all components\n- `<trace>` elements connecting all required pins\n- Decoupling capacitors near every IC power pin (100nF ceramic, 0402 or 0603)\n- Pull-up/pull-down resistors where the datasheet or protocol requires them (e.g., I2C needs pull-ups)\n\n**Component naming conventions:**\n- U1, U2... for ICs\n- R1, R2... for resistors\n- C1, C2... for capacitors\n- L1, L2... for inductors\n- D1, D2... for diodes/LEDs\n- J1, J2... for connectors/headers\n- SW1, SW2... for switches\n- Q1, Q2... for transistors\n\n**Placement strategy:**\n- Place the main IC at or near center (0, 0)\n- Group related components near their IC\n- Keep decoupling caps within 2-3mm of their IC's power pins\n- Place connectors at board edges\n- Leave ~2mm clearance from board edges\n- Space components enough for the autorouter (minimum ~2mm between unrelated parts)\n\n### Step 6: Deliver to User\n\nCreate 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.\n\n1. **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)\n2. **Write a `README.md`** in that folder containing:\n - Project name and one-line description\n - Design assumptions (voltages, interfaces, component choices)\n - Bill of Materials summary (component, value, footprint, quantity)\n - How to run: `bun update --latest`, then `bun run start`\n - Pin mapping / net summary for the user's firmware\n - Any known limitations or things the user should verify\n3. **Use `present_files`** to share the key output files (index.tsx, README.md) with the user\n\nExample delivery commands:\n```bash\n# Create output directory with .vscode subfolder\nmkdir -p /mnt/user-data/outputs/esp32-bme280-board/.vscode\n\n# Copy source files ONLY — never use cp -r on the project root (leaks node_modules)\nfor f in package.json tsconfig.json tscircuit.config.json bunfig.toml .npmrc .gitignore index.tsx README.md; do\n cp \"/home/claude/esp32-bme280-board/$f\" \"/mnt/user-data/outputs/esp32-bme280-board/$f\"\ndone\ncp /home/claude/esp32-bme280-board/.vscode/*.json /mnt/user-data/outputs/esp32-bme280-board/.vscode/\n```\n\nThe output folder will contain:\n```text\n/mnt/user-data/outputs/esp32-bme280-board/\n .gitignore\n .npmrc\n bunfig.toml\n package.json\n tscircuit.config.json\n tsconfig.json\n index.tsx ← the actual circuit design\n README.md ← design notes, BOM, instructions\n .vscode/\n settings.json\n tasks.json\n```\n\n**⚠️ Never include `node_modules/` in the output.** The user installs dependencies themselves with `bun update --latest`.\n\n## tscircuit Quick Reference\n\n### Core Elements\n\n```tsx\n// Board — root container, everything goes inside\n<board width=\"50mm\" height=\"40mm\">\n {/* components and traces */}\n</board>\n\n// Resistor — non-polar, 2 pins: pin1/pin2 (aliases: pos/neg)\n<resistor name=\"R1\" resistance=\"10k\" footprint=\"0402\" pcbX={5} pcbY={3} />\n\n// Capacitor — 2 pins: pin1/pin2 (aliases: pos/neg for polarized)\n<capacitor name=\"C1\" capacitance=\"100nF\" footprint=\"0402\" pcbX={2} pcbY={1} />\n\n// LED — 2 pins: anode(pos)/cathode(neg)\n<led name=\"LED1\" footprint=\"0603\" color=\"green\" pcbX={10} pcbY={0} />\n\n// Diode\n<diode name=\"D1\" footprint=\"sot23\" pcbX={0} pcbY={5} />\n\n// Generic IC via <chip> — the workhorse element\n<chip\n name=\"U1\"\n footprint=\"soic8\"\n pinLabels={{\n pin1: \"VCC\", pin2: \"OUT\", pin3: \"NC\", pin4: \"GND\",\n pin5: \"TRG\", pin6: \"THR\", pin7: \"DIS\", pin8: \"RST\"\n }}\n connections={{ // shorthand for traces\n VCC: \"net.VCC\",\n GND: \"net.GND\",\n }}\n pcbX={0} pcbY={0}\n/>\n\n// Pin header — for GPIO breakout, programming, etc.\n<pinheader name=\"J1\" pinCount={6} pitch=\"2.54mm\" pcbX={-20} pcbY={0} />\n\n// Traces — connect pins together\n<trace from=\".R1 > .pin1\" to=\".U1 > .OUT\" /> // direct pin-to-pin\n<trace from=\".C1 > .pin1\" to=\"net.GND\" /> // connect to named net\n```\n\n### Footprint Strings\n\n| Type | Examples |\n|------|---------|\n| Passives | `0402`, `0603`, `0805`, `1206` |\n| SOIC | `soic8`, `soic14`, `soic16`, `soic16_w7mm_p0.8mm` |\n| QFP/TQFP | `qfp32`, `qfp48`, `tqfp32`, `tqfp48` |\n| QFN | `qfn20`, `qfn24`, `qfn32`, `qfn24_w6_h6_p0.8mm` |\n| BGA | `bga9`, `bga16`, `bga16_p2mm` |\n| TSSOP/SSOP | `tssop8`, `tssop16`, `tssop20`, `ssop8` |\n| SOT | `sot23`, `sot23_5`, `sot223` |\n| DIP | `dip8`, `dip14`, `dip16`, `dip8_wide` |\n| Pin rows | `pinrow4`, `pinrow8`, `pinrow10` |\n| TO packages | `to92`, `to220` |\n| Stampboard | `stampboard` (for module-style packages) |\n\n### Trace Addressing\n\n```text\n\".ComponentName > .pinLabel\" — by label (preferred when pinLabels are set)\n\".ComponentName > .pin1\" — by pin number\n\"net.VCC\" — named power net\n\"net.GND\" — ground net\n\"net.SDA\" — named signal net\n```\n\n### Reusable Subcomponents\n\n```tsx\nimport type { CommonLayoutProps } from \"tscircuit\"\n\ninterface RegProps extends CommonLayoutProps {\n name: string\n}\n\nexport const AMS1117_3V3 = (props: RegProps) => (\n <chip\n footprint=\"sot223\"\n pinLabels={{ pin1: \"GND\", pin2: \"VOUT\", pin3: \"VIN\" }}\n {...props}\n />\n)\n```\n\n### Board Options\n\n```tsx\n<board\n width=\"50mm\"\n height=\"40mm\"\n layers={4} // 2 (default) or 4 layer stackup\n defaultTraceWidth=\"0.25mm\"\n minTraceWidth=\"0.15mm\"\n autorouter=\"auto-cloud\" // use for >50 traces\n borderRadius=\"2mm\" // rounded corners\n>\n```\n\n## Critical Design Rules\n\n1. **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.\n\n2. **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.\n\n3. **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).\n\n4. **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.\n\n5. **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.\n\n6. **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.\n\n7. **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).\n\n8. **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Ω).\n\n9. **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Ω).\n\n10. **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.\n\n## Project Specific Instructions\n\ntscircuit uses `bun`, so the correct command to run the dev server is `bun run start`, **not** `npm run dev` or `npm start`.\n\n**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.\n\nWhen writing README files or explaining next steps to the user, always use:\n\n```bash\n# First time setup (in the project directory)\nbun update --latest # update all tscircuit dependencies to latest\n\n# Launch dev server with live PCB/schematic/3D preview\nbun run start\n```\n\nOther useful tscircuit CLI commands:\n```bash\ntsci export gerber # export Gerber fabrication files\ntsci export bom # export Bill of Materials\ntsci export pnp # export Pick-and-Place file\n```\n\n## Reference Files\n\n- `references/tscircuit-elements.md` — Detailed element API reference (read for unfamiliar elements)\n- `references/common-circuits.md` — Complete design patterns: power, MCU, sensors, USB, LEDs\n",
"author": {
"id": "695820315b5f1e4db2fcf602",
"name": "Kyle Bergstedt",
"email": "[email protected]"
},
"visibility": {
"public": true
},
"hero": null,
"discovery_triggers": [],
"discovery_pitch": null,
"metadata": {},
"created_at": "2026-05-28T05:29:43.117Z",
"updated_at": "2026-05-28T05:29:43.117Z",
"sub_skills": [],
"parent_app": null
}