From kicad-jlcpcb
Automates KiCad to EasyEDA to JLCPCB PCB workflow: project setup, LCSC part sourcing, pin-map fetching, fully-wired .kicad_pcb generation via pcbnew, and EasyEDA handoff for routing and ordering.
How this skill is triggered — by the user, by Claude, or both
Slash command
/kicad-jlcpcb:kicad-jlcpcb-workflowThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Help the user take a PCB project from "I want a board that does X" to "I clicked Order in EasyEDA and it's on its way from JLCPCB." The plugin automates parts sourcing, pin-map lookup, footprint placement, and net wiring — which was the slow tedious part. Routing and ordering happen in EasyEDA's web app because its cloud auto-router handles real boards (including RF) far more reliably than anyt...
Help the user take a PCB project from "I want a board that does X" to "I clicked Order in EasyEDA and it's on its way from JLCPCB." The plugin automates parts sourcing, pin-map lookup, footprint placement, and net wiring — which was the slow tedious part. Routing and ordering happen in EasyEDA's web app because its cloud auto-router handles real boards (including RF) far more reliably than anything shippable headlessly.
detect_kicad, create_project (or load_project)lcsc_search, lcsc_resolve_bompart_pin_map (auto-called by pcb_generate, but you can inspect individual parts)pcb_generate produces the wired .kicad_pcbeasyeda_handoff gives the user the import instructionsEvery project writes a .kicad_jlcpcb_session.json to its root that tracks which stages have completed (project_created → parts_sourced → bom_confirmed → pcb_generated → handoff_rendered).
When the user points /pcb-new or /pcb-from-bom at a path that already has a project:
load_project on it. The response includes a session summary and resume_available: true if the prior workflow got past stage created.bom / spec and skipping the stages that are already done. Starting fresh means deleting .kicad_jlcpcb_session.json (or picking a different directory) so the workflow begins at stage created again.session_resume directly on any project directory to inspect state without loading the project as the active workspace.Use this generously — Claude Code restarts are common mid-flow, and the session file makes resuming cheap.
I tried shipping headless Freerouting in an earlier phase. It doesn't work on RF boards (RF matching networks with picofarad/nanohenry components create maze-search constraints the open-source router can't solve). It also has a known CLI bug where -mp is ignored and it won't save partial results. EasyEDA's cloud auto-router handles the same boards reliably and it's owned by the same company as JLCPCB, so ordering is a single click. The plugin stops at "wired .kicad_pcb" because that's the boundary where automation breaks down in the open-source world but works cleanly in EasyEDA.
Phase 1.6 enforces one hard checkpoint: after BOM resolution, before PCB generation. Always show the user:
estimated_setup_fee_usd totalunresolvedAsk whether to swap any extended parts for basic alternatives. Do not call pcb_generate until the user confirms.
JLCPCB charges ~$3 per unique extended-library part as a one-time SMT assembly setup fee. For a small-batch board, 10 extended parts = $30 extra regardless of quantity. The plugin's lcsc_resolve_bom tallies this automatically.
Decision tree per component:
Need a part →
lcsc_search(basic_only=True)
Got results? → pick the top by stock
No results? →
lcsc_search(basic_only=False)
Got results? → warn user with cost impact, ask
No results? → mark unresolved, ask user for guidance
pcb_generate consumes a dict with this shape:
{
"name": "soilnode",
"board": {"width_mm": 80, "height_mm": 60, "layer_count": 2},
"components": [
{
"ref": "U1",
"value": "ESP32-C3-WROOM-02",
"lcsc": "C2934560",
"lib": "RF_Module",
"fp": "ESP32-C3-WROOM-02"
},
{
"ref": "R1",
"value": "10k",
"lcsc": "C25804",
"lib": "Resistor_SMD",
"fp": "R_0603_1608Metric"
}
],
"nets": {
"3V3": [["U1", "3V3"], ["R1", "1"]],
"GND": [["U1", "GND"], ["R1", "2"]],
"I2C_SCL": [["U1", "GPIO9"], ["U3", "SCL"]]
}
}
Critical rule: reference IC pins by NAME, not number. The plugin auto-fetches pin maps from EasyEDA for any component with an lcsc field. You write ["U1", "GPIO10"] and the plugin resolves it to the right pad number. For passives (resistors, caps) use bare pad numbers "1" and "2".
If you need to know what pin names a specific IC exposes (e.g. is it "VCC" or "VDD", "GND" or "VSS"?), call part_pin_map with the C-number before building the spec:
part_pin_map(lcsc="C82942")
→ {
"title": "ME6211C33M5G-N",
"pin_count": 5,
"pinmap": {"VIN": "1", "VSS": "2", "CE": "3", "NC": "4", "VOUT": "5"}
}
Now you know the LDO uses VIN/VSS/VOUT not VCC/GND/VOUT, and you can write nets that match.
The plugin loads footprints from /usr/share/kicad/footprints/<lib>.pretty/<fp>.kicad_mod. Common picks:
| Component | lib | fp |
|---|---|---|
| Resistor 0402/0603/0805 | Resistor_SMD | R_0402_1005Metric / R_0603_1608Metric / R_0805_2012Metric |
| MLCC 0402/0603/0805 | Capacitor_SMD | C_0402_1005Metric / C_0603_1608Metric / C_0805_2012Metric |
| SOT-23-5 (LDO) | Package_TO_SOT_SMD | SOT-23-5 |
| SOT-23-6 (dual FET, protection IC) | Package_TO_SOT_SMD | SOT-23-6 |
| VSSOP-10 (ADS1115) | Package_SO | VSSOP-10_3x3mm_P0.5mm |
| QFN-24 w/ EP (SX1262) | Package_DFN_QFN | QFN-24-1EP_4x4mm_P0.5mm_EP2.7x2.7mm |
| DFN-8 (CN3065) | Package_DFN_QFN | DFN-8-1EP_3x3mm_P0.65mm_EP1.55x2.4mm |
| SOIC-8 | Package_SO | SOIC-8_3.9x4.9mm_P1.27mm |
| ESP32-C3 module | RF_Module | ESP32-C3-WROOM-02 |
| USB-C 16P | Connector_USB | USB_C_Receptacle_HRO_TYPE-C-31-M-12 |
| JST-PH 2/3 pin | Connector_JST | JST_PH_B2B-PH-K_1x02_P2.00mm_Vertical / JST_PH_B3B-PH-K_1x03_P2.00mm_Vertical |
| Crystal 3225 | Crystal | Crystal_SMD_3225-4Pin_3.2x2.5mm |
| 0603 LED | LED_SMD | LED_0603_1608Metric |
| Tactile switch SMD | Button_Switch_SMD | SW_SPST_TL3342 (4 copper pads, 2 nets: pad "1" + pad "2") |
If the user asks for a part you don't have in this reference, search /usr/share/kicad/footprints/ directly via Bash (e.g. ls /usr/share/kicad/footprints/Package_DFN_QFN.pretty/ | grep DFN-8) and pick the closest match by dimensions.
The EasyEDA pin-name extraction is accurate but uses datasheet nomenclature, which doesn't always match what humans call pins. Two examples that bit us during the SoilNode trial:
part_pin_map before writing nets if you're uncertain.detect_kicad returns meets_min: false — pass the install_hint through verbatim.lcsc_resolve_bom unresolved rows — show and ask for substitutions.part_pin_map raises "no component data" — that LCSC number isn't in EasyEDA's library. You'll need to hardcode the pinmap in the component spec (provide a "pinmap": {...} field).pcb_generate errors list non-empty — check each error:
"X: Footprint not found" — wrong lib/fp name, look in /usr/share/kicad/footprints/"net X: Y has no pad Z" — pin name doesn't match EasyEDA's data, call part_pin_map and fixpcb_generate on fresh ICs can pause up to ~12 seconds per unique IC. Subsequent runs are instant.references/jlcpcb-rules.md — JLCPCB design rules, cost model, manufacturing file requirementsreferences/lcsc-search.md — How the jlcparts mirror and SQLite cache workreferences/troubleshooting.md — Quick reference for common runtime failure modesexamples/soilnode-esp32/ in the repo root — full spec, BOM, and step-by-step walkthroughnpx claudepluginhub beckhamlabsllc/kicad-jlcpcbGenerates BOM/CPL files for JLCPCB PCB fabrication and assembly, handles basic vs extended parts, design rules, and ordering workflow. Use with KiCad for JLCPCB manufacturing.
Guides EasyEDA Pro workflows via EasyEDA MCP Pro: server setup, schematic/PCB inspection, controlled writes, exports, BOM/DRC/ERC, and status reporting.
Downloads KiCad footprints, symbols, and 3D models from LCSC/EasyEDA for JLCPCB PCBA projects using LCSC part numbers.