Skip to main content

LLM-assisted JLCPCB part mapping for KiCad schematics

Project description

jlcpcb-mapper

한국어 README

LLM-assisted part mapping from KiCad schematics to JLCPCB's LCSC catalog. Reads symbols that don't yet have a footprint or LCSC, scores candidates against the local parts.db, asks Claude Code to break ties on ambiguous picks, then writes the LCSC and KiCad footprint back into the schematic.

What problem this solves

Hand-mapping every passive, IC, and connector in a KiCad project to a JLCPCB part is tedious and easy to get wrong — same value, different package; correct package, EOL stock; SMD label, leaded part. This tool automates the mechanical 80% (resistors, ceramic caps, common diodes and MOSFETs by MPN, etc.) and gives you a Markdown review document that explains why it picked each part, with LCSC.com links and alternatives, so the human review step is a quick read-through rather than a search session.

How it works

The pipeline runs per group (symbols sharing the same category + spec + package hint):

  1. Match — route each empty-LCSC symbol to a category by lib_id (Device:R → resistor, Device:CP → polarized_capacitor, Device:FerriteBead → ferrite_bead, anything else with a : → ic).
  2. Parse — extract a structured spec from the Value field ("4.7uH/2A" → inductance + minimum current rating).
  3. Query — pull candidates from parts.db by category, package, and description LIKE on the value.
  4. Decide — three paths:
    • single — only one candidate after filtering.
    • scoreBasic-tier × stock-bucket × tier-specific dimensions deterministic score; if the gap to the runner-up exceeds a threshold, accept it.
    • llm — close call → send the top-N to Claude Code for a tiebreak with an explicit reason.
  5. Resolve footprint — KiCad built-in mapping for common SMD passives; on-the-fly EasyEDA download (via the kicad-jlcpcb-tools helper) for anything else.

Manual overrides bypass the pipeline entirely — see Manual overrides.

Prerequisites

  • KiCad 9 project (*.kicad_pro, *.kicad_sch).
  • A JLCPCB parts SQLite catalog. The standalone jlcpcb-mapper fetch-db command builds one — see the Quick start below. If you already use kicad-jlcpcb-tools and have run its "Download parts data" step, the tool also auto-detects that DB.
  • Claude Code CLI (claude) on PATH. Used for tiebreaks; the pipeline still runs without it (deterministic score path only) but quality will drop.
  • Python 3.11+ and uv or pipx for installation.

Install

pipx install jlcpcb-mapper
# or for development:
uv venv && source .venv/bin/activate
uv pip install -e ".[dev]"

Quick start

jlcpcb-mapper fetch-db                      # one-time: download parts.db (~1 GB → slim DB)
cd /path/to/my-kicad-project
jlcpcb-mapper init                          # scaffolds jlcpcb-mapper.yaml
jlcpcb-mapper map my-project.kicad_pro      # writes LCSC + footprint
# Review the generated report:
open .jlcpcb-mapper/run-<latest>.md
git diff                                    # eyeball schematic changes

fetch-db writes to ~/.cache/jlcpcb-mapper/parts.db by default and the tool auto-detects it from there.

The tool refuses to run on a dirty git tree (override with --force) so you can always reach a known-good state with git checkout . if the mapping is off.

End-to-end workflow

A typical first-time mapping on a KiCad board.

1. Get parts.db ready

jlcpcb-mapper fetch-db

Downloads JLCPCB's parts data and builds a slim SQLite catalog at ~/Library/Caches/jlcpcb-mapper/parts.db (macOS) / ~/.cache/jlcpcb-mapper/parts.db (Linux). One-shot, ~1 GB of zip chunks fetched once and reduced to a ~100 MB DB. Re-run periodically to refresh stock and pricing.

If you already have the kicad-jlcpcb-tools plugin set up in KiCad with its parts data downloaded, jlcpcb-mapper also auto-detects that DB — no need to fetch twice. You can override the path explicitly via parts_db: in the config.

2. Initialize the config

jlcpcb-mapper init

Edits a jlcpcb-mapper.yaml next to your *.kicad_pro. The defaults are reasonable for hobby boards (0402 passives, X7R/X5R caps, min_stock 1000); read Configuration for tuning.

3. Run the mapper

jlcpcb-mapper map my-project.kicad_pro

What happens:

  • Schematics are read.
  • Symbols are filtered: must be on-board, must have a Value, must not be a power:* symbol, must have an empty Footprint AND empty LCSC.
  • Each remaining symbol is routed to a category and grouped with its twins.
  • Each group runs through query → score → (optional) LLM tiebreak.
  • A timestamped backup of every modified .kicad_sch is written to .jlcpcb-mapper/backups/<ts>/.
  • The schematics are atomically rewritten with new LCSC and Footprint values.
  • A Markdown report (.jlcpcb-mapper/run-<ts>.md) and JSON log (run-<ts>.json) are written.

4. Review the report

Open .jlcpcb-mapper/run-<latest>.md. Each grouped pick looks like:

### resistor 4700Ω 0402 — 20 refs (R20, R21, R22, R23, R24, R50, … +14 more)

**Selected**: [`C25744`](https://www.lcsc.com/product-detail/C25744.html) — UNI-ROYAL 0402WGF4701TCE
- **Package** `0402` · **Tier** Basic · **Stock** 4.4M · **Price** $0.0009
- 4.7kΩ 1% 1/16W 0402 Chip Resistor

**Why this part?** Score 1.00 vs runner-up 0.40 — Basic-tier (vs Extended), higher stock (4.4M vs 60k).

**Alternatives considered**:

| LCSC | Mfr Part | Tier | Package | Stock | Price | Score |
|------|----------|------|---------|-------|-------|-------|
| [`C123456`](…) | YAGEO RC0402FR-… | Extended | 0402 | 60k | $0.0007 | 0.40 |
| …

The "Why this part?" line distinguishes:

  • single — only candidate after filtering.
  • score — which dimension dominated (Basic-tier, stock, voltage match).
  • llm — Claude's own one-sentence reasoning passed through.
  • manual — pinned in config (no scoring).

5. Approve or revert

git diff                # see what changed
git checkout .          # revert if you don't like it

If you accept, commit the schematic changes alongside your config.

6. Re-check before fab

jlcpcb-mapper verify my-project.kicad_pro

Re-runs the lookup against the current parts.db and warns if any mapped LCSC has dropped below verify.min_stock_warning or the price has moved by more than verify.price_change_pct_warning.

Configuration

jlcpcb-mapper.yaml lives next to your *.kicad_pro. Defaults come from default_config.yaml shipped with the package; the user file overrides keys you set, deep-merged.

Selection rules

selection:
  prefer_order: [basic, preferred, extended]
  min_stock: 1000
  defaults:
    resistor:
      package: "0402"
      tolerance: "1%"
      power: "1/16W"
    capacitor:
      package: "0402"
      voltage_min: 10
      dielectric_prefer: [X7R, X5R]
    led:
      package: "0603"

prefer_order only affects scoring weights. min_stock is a hard SQL filter — anything below it never even reaches the scoring path.

LLM hints

hints: |
  - Prefer Basic parts with high stock.
  - Avoid parts with stock < 10000 (EOL risk).

Free-form text appended verbatim to the LLM prompt. Useful for project-specific rules ("avoid Y5V dielectric", "prefer AEC-Q200 for the automotive section", …).

Tiebreak thresholds

score_tiebreak_threshold: 0.1   # accept score-path pick if top - second >= this
llm_tiebreak_top_n: 5           # otherwise send this many top rows to the LLM

Manual overrides for subjective picks

manual_lcsc:
  by_reference:
    J2: C16214      # 2.0mm DC barrel jack (DC-005 2.0)
    J3: C165948     # USB-C 16P SMD (TYPE-C-31-M-12)
    J1: C492421     # 2.54mm 2x4 pin header (PZ254V-12-8P)
  by_value:
    "POGO (1PI)": C5221287   # all 12 pogo-pin symbols at once
    "SW_SPST":    C7470157   # 6×6 tactile switch

by_reference (exact ref designator) wins over by_value (matches the symbol's Value field, useful when many symbols share the same choice). The LCSC is written without scoring; if it isn't in parts.db it surfaces as a manual_unknown_lcsc failure and the auto pipeline retains the ref. Existing footprints are preserved — manual mode only writes the LCSC.

Footprint overrides

kicad_footprint_map_overrides:
  resistor:
    "0402": "MyLib:R_0402_HouseStyle"

Per-(category, package) → footprint identifier. Useful when your in-house library has stricter pad geometry than KiCad's stock footprint.

Output artifacts

Each map run creates, under .jlcpcb-mapper/:

File Purpose
run-<ts>.json Machine-readable summary: schematics, eligibility counts, per-source counts (single, score, llm, manual, failed), per-group outcomes, failure list.
run-<ts>.md Human review document — what this README's report example shows.
traces/<ts>/groups.jsonl One JSON line per group with the full per-stage trace (match → parse → extract → query → post_filter → score breakdown → decide → resolve). Stable list order; timestamp_ms is monotonic.
traces/<ts>/index.json reference → line offset map for fast explain <ref> lookups.
backups/<ts>/ A copy of every modified .kicad_sch taken before the atomic write.

Flags

map--config PATH, --non-interactive, --force, --allow-stale-db, --fill-lcsc-only, --include-dnp, --apply-2nd-pass-suggestions

verify--config PATH, --non-interactive, --force, --allow-stale-db

--fill-lcsc-only widens target selection to "any symbol missing an LCSC" regardless of footprint state. Useful when KiCad's symbol library already provided a footprint and you only need the LCSC to finish the BOM.

Categories supported

resistor, ceramic_capacitor, polarized_capacitor, inductor, ferrite_bead, led, crystal, connector, ic (catch-all by MPN). Anything outside these — mounting holes, custom pogo pins, USB-C receptacles, mechanical switches — is best handled via manual_lcsc overrides.

Status

v0.1 — used and validated against real KiCad projects (≈150 eligible symbols, ~75% exact-match rate against hand-picked parts). See docs/ for design notes.

Future work

  • Schematic-context-aware part selection. Today the tool picks parts from the symbol Value + footprint package alone. The richer decision — "this 100nF cap sits on a 3.3 V LDO output, so 16 V X7R is fine but 6.3 V Y5V isn't"; "this 4.7 µH inductor carries the switcher's output current, so it needs ≥ 2× the load rating" — is still on the human reviewer. Net topology, voltage-domain inference, and per-net current estimates would let the LLM tiebreak with full context instead of just the symbol's local fields.

Acknowledgments

The parts.db schema and the upstream JLCPCB parts feed both come from kicad-jlcpcb-tools and yaqwsx/jlcparts. This project is a separate front-end that consumes the same data; it doesn't replace those tools.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

jlcpcb_mapper-0.1.1.tar.gz (113.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

jlcpcb_mapper-0.1.1-py3-none-any.whl (65.0 kB view details)

Uploaded Python 3

File details

Details for the file jlcpcb_mapper-0.1.1.tar.gz.

File metadata

  • Download URL: jlcpcb_mapper-0.1.1.tar.gz
  • Upload date:
  • Size: 113.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for jlcpcb_mapper-0.1.1.tar.gz
Algorithm Hash digest
SHA256 e446ee3eb6831d63c9b8c6f93d992b5273dfcfedc7922a7f8f0782f9ed46d13d
MD5 dec1c413e5f9b33637c3532f680eedfe
BLAKE2b-256 bf5d7327354ac9dd0e529c832e9afc5ae03827d187bb24a6b96a46f09bfeab49

See more details on using hashes here.

File details

Details for the file jlcpcb_mapper-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: jlcpcb_mapper-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 65.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for jlcpcb_mapper-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 e144882fef6de1f029e63c62b81e0e55d658fcf957a45bdebb49f04905cf92eb
MD5 8182216f176b8114e1951953e9ffe8a9
BLAKE2b-256 80d32501b0ba952e0db98f2bfbf4c59121e5749ed6293da1af0645cedc6bc877

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page