If you order PCB assembly from JLCPCB, they ask for two files on top of your Gerbers: a BOM (what to place) and a CPL (where to place it). Getting the columns and values exactly right is the difference between a smooth order and a round of rejection emails.

Short answer: JLCPCB reads a BOM keyed by Designator + LCSC Part # (with Comment/Value and Footprint for context), and a CPL (pick-and-place) file with Designator, Mid X, Mid Y, Layer, Rotation. Match those column names, put a real LCSC part number on every placed line, and confirm rotations, and your order sails through.

The BOM file JLCPCB expects

The BOM tells JLCPCB what to buy and place. It is a simple CSV or Excel sheet, one row per unique part (grouped by value), with these columns:

  • Comment (or Value) — the human-readable part value, e.g. 10k, 100nF, ESP32-WROOM-32E. This is for your own reference and for the reviewer; it does not have to be machine-perfect.
  • Designator — every reference designator that uses this part, comma-separated: R1,R2,R5. This is how the BOM line maps to physical placements in the CPL.
  • Footprint — the package, e.g. R_0402, C_0603, SOT-23. JLCPCB cross-checks this against the LCSC part's real package to catch mismatches.
  • LCSC Part # — the catalog number of the exact part in LCSC's inventory, e.g. C25744. This is the load-bearing column. JLCPCB sources parts by this number, not by the value text. A blank here means "do not place" or a rejection.

BOM example

Comment Designator Footprint LCSC Part #
10k R1,R2,R5 R_0402 C25744
100nF C1,C2,C3,C4 C_0402 C1525
ESP32-WROOM-32E U1 ESP32-WROOM-32 C701342

That is the whole contract on the BOM side: a value for humans, a designator list for mapping, a footprint for sanity-checking, and an LCSC number that resolves to a real reel.

The CPL / pick-and-place file JLCPCB expects

The CPL (also called the "component placement list" or pick-and-place file) tells the machine where each part goes and how it is oriented. One row per placed component:

  • Designator — the reference designator, e.g. R1. This links back to the BOM by the same name.
  • Mid X — the X coordinate of the component's center, with units (mm). JLCPCB expects the part center, not a pin-1 or origin corner.
  • Mid Y — the Y coordinate of the component's center.
  • LayerTop or Bottom, telling the line which side of the board to place on.
  • Rotation — orientation in degrees, counter-clockwise, 0360.

CPL example

Designator Mid X Mid Y Layer Rotation
R1 22.500mm -15.000mm Top 90
C1 18.250mm -12.100mm Top 0
U1 30.000mm -20.000mm Top 270

Every designator that appears in the CPL should have a matching part on a BOM line (via that comma-separated designator list). Parts you do not want assembled — mounting holes, test points, "do not place" items — simply stay off the BOM even if they appear in your layout.

How this maps from KiCad's native exports

KiCad produces both files, but the default output does not carry JLCPCB's column names or its assumptions, so a little remapping is normal.

  • BOM. kicad-cli sch export bom (or the schematic BOM tool) exports fields from your schematic. You group by value and emit Value, Reference (the designator list), Footprint, and a custom LCSC field. The catch: KiCad has no built-in "LCSC" column — you add a symbol field (commonly named LCSC or LCSC Part #) to each component, then export that field. See KiCad BOM with LCSC part numbers for the field-setup details.
  • CPL. kicad-cli pcb export pos writes a position file with Ref, PosX, PosY, Side, and Rot. Those are exactly JLCPCB's five columns under different names — you rename Ref → Designator, PosX → Mid X, PosY → Mid Y, Side → Layer, and Rot → Rotation. Export in mm, using the board's own coordinate origin.

The single most common surprise is rotation. KiCad and LCSC do not always agree on a package's "zero" orientation, so a part can look correct in KiCad yet land rotated 90 or 180 degrees on the line. Polarized and multi-pin parts (diodes, electrolytics, ICs, connectors) are where this bites — always spot-check them against JLCPCB's preview.

The most common rejection reasons

Almost every rejected assembly order traces back to one of these:

  1. Missing or blank LCSC part number. The single biggest cause. A BOM line with no LCSC number cannot be sourced. Either add the number or intentionally exclude the part.
  2. Wrong rotation. Off by 90 or 180 degrees, usually on diodes, electrolytic caps, ICs, and connectors. The board is placed, but the part is oriented wrong.
  3. Footprint mismatch. The BOM says 0402 but the LCSC part is 0603, or the package name does not match the real component. JLCPCB's reviewer flags the discrepancy.
  4. Unrecognized headers. Column names their parser does not know — Reference instead of Designator, PosX instead of Mid X, or a merged/blank header row. Match the expected names exactly.
  5. Empty part-number column, or designator mismatch. Designators in the CPL that have no BOM line (or vice versa), and coordinate columns exported in the wrong units or from the wrong origin.

First-time checklist

Run through this before you upload and you will almost always clear review on the first try:

  • BOM headers are Comment/Value, Designator, Footprint, LCSC Part #.
  • Every placed line has a real LCSC number (C…); "do not place" parts are removed from the BOM.
  • Footprints match the actual LCSC package (0402 vs 0603, SOT-23 variants, etc.).
  • CPL headers are Designator, Mid X, Mid Y, Layer, Rotation.
  • Mid X / Mid Y are component centers, in mm, from a consistent origin.
  • Layer is Top or Bottom for every row.
  • Rotations checked on polarized and multi-pin parts against JLCPCB's on-screen preview.
  • Every CPL designator has a matching BOM line and vice versa.

Let the pipeline produce them for you

Hand-editing headers and eyeballing rotations every revision is exactly the kind of chore that goes stale the moment your board changes. GoForFab runs kicad-cli on every push and emits a JLCPCB-format BOM and CPL automatically — the same output the popular Fabrication Toolkit produces — with the columns already named right and pulled straight from your current design. It is free forever, and it means the files you upload always match the board you just pushed. If you want the bigger picture on packaging outputs for a fab, see preparing a professional manufacturing handoff.

Get the two files right once and JLCPCB assembly stops being the scary part of ordering a board.