Using KiCad with JLCPCB Assembly Service

TLDR: Click here.

A Bit of History

I remember when I first started making PCBs in ~2010, our low spec (8 mil min traces / 8 mil min spacing) 2-layer boards costed $133 for 4 copies. Special academic pricing.

There were services like Sparkfun’s BatchPCB and OSH Park that were quite a bit cheaper, but generally took about a month to deliver, as they batched together designs from many customers on each panel to amortise the cost. Great if you are very patient, but not very useful if you have any deadline.

And then the Chinese prototyping services popped up, I think around 2012, and started getting popular. Of course, most production PCBs had been made in China for at least a decade at this point, but I believe this is the first time Chinese companies started targeting the low quantity prototyping market. If my memory serves, Seeedstudio was the first with their Fusion PCB service, and ITeadStudio was, as always, the first copycat. They offered about the same specs as the fabs we have been using, but for $10-$20 per 10 boards, though they still had the problem of long lead time (and high shipping cost from China if you want your boards fast).

Fast forward a few years to 2019, and now there are many similar services out there, offering even lower prices (as low as $2 for 10 boards!), very fast turnaround (24-72 hours), and very high specs (5/5 mils or even 3.5/3.5 mils). Very interesting options have also become available – ENIG finish, different substrates (eg. flex or aluminium for high power applications), different copper thicknesses, and 4+ layers for reasonable prices.

I have tried most of them at least once, and they are largely interchangeable unless you want very specific options. PCB prototyping is now a commodity, so now they are looking for other ways to differentiate, and assembly seems to be one such area. As hobbyists we have already given up making PCBs at home. Wouldn’t it be great if we can get someone to do the soldering as well?

I believe Seeedstudio was again one of the first to offer this service, but they assemble low quantity PCBs by hand, and reviews were scathing – bad solder joints, missed parts, parts installed in wrong orientation, etc. That’s why I never tried it. It didn’t seem like we would get high quality assembly until someone starts offering automatic pick-and-place for low quantity boards.

I was very excited when JLC started offering just that recently. They have a bunch of pick and place machines already set up with 600+ common components, and they can also load up new components for you at $3/component type, from their 30k+ components library. They are owned by the same company as LCSC, the biggest electronic component distributor in China, so that’s how they can get such an extensive library of components. Of course, with Chinese-sourced components there is always a chance of fakes. Time will tell how big of a problem that is – at least LCSC and JLC are very big companies that do have pretty good reputations they can lose, so it’s still not like ordering random components from eBay.

As far as I can tell their entire process is automated (besides presumably loading up reels that they charge $3/each for), and that also comes with downsides – no thru-hole components, and you can only use components they have in stock (unlike most assembly services, you can’t supply components for them to use). Unfortunately they don’t have any connectors in their library, so if you want a USB connector for example, you still have to solder that yourself. The reason they gave is that they panelise boards for assembly, and board-edge connectors make it difficult. However, besides that, their library is pretty extensive, with even some stock of high end microcontrollers like STM32F7, and lots of STM32F4.

The Process

I have developed a process for using their service with KiCad, and wrote a script to generate the files they need, so here is a walkthrough.

  1. Design your board as usual, but…
    • Make sure all the SMT parts you want assembled are on the same side.
    • Choose parts from their library. Add the Cxxxxx code to your components in Eeschema by adding a custom field (call it anything you want). That’s what my script will pick up later on. Anything that doesn’t have a Cxxxx code won’t be assembled.
  2. Once you are satisfied with your board design, go to Eeschema and run “Tools -> Generate Bill of Materials” to generate a BOM in any format/plugin. We don’t actually need the generated BOM file, but this process will produce an intermediate netlist file in XML format that we need later (not the same as KiCad’s standard netlist).
  3. Go to Pcbnew and run ‘File -> Fabrication Outputs -> Footprint Position (.pos) File’.
    • CSV format, mm unit, and ‘single file for board’
  4. Plot gerbers as per usual for PCB manufacturing – all copper layers, front mask, back mask, front silk, back silk, Edge.Cuts (for board border). Not sure if the paste layers are needed (given they are doing the assembly), but I include them in my zip file anyways and they don’t seem to mind.
  5. Run my script and give it the project directory. It will look for the files it needs in the given project directory and all sub-directories, and let you know if it can’t find anything.
    • Follow the instructions here to install and run the script:
    • If all goes well, the script will tell you where the BOM and CPL files generated are (inside your project directory). If not, read the error message and fix anything that needs fixing.
  6. Go to the order page and upload gerbers and pick options as usual. Keep in mind that only green soldermask and 1oz copper is supported for assembly. In ‘SMT Assembly’, click the button to enable assembly. Pick a side to assemble, and confirm.
  1. Upload the files generated by the script. Next.
  2. You’ll get a list of matched parts found. Check each one, and click “confirm”. You have to confirm every part before you can proceed.
  1. Very important: Zoom in on the mockup diagram, and make sure all the polarities and orientations as indicated are correct. Some of them probably won’t be, because KiCad footprints seem to have different canonical orientations.
  2. Note down the footprints with incorrect rotations, and the additional rotation required to make them correct (positive is clockwise).
  3. Edit ‘cpl_totations_db.csv’ in the same directory as the conversion script to add those footprints. The first column is the footprint pattern to match in regex, and the second column is rotation correction.
  4. Run the script again to generate new BOM and CPL files. Go back on the JLC page and upload those new files. Repeat until all orientations are correct, and place the order! Keep in mind that unless you are using very expensive components, the price for 10 boards will be very similar to the price for 5 boards (minimum quantity) because most of the cost is in setup. I would order 10 if there’s any chance that you’ll need more than 5.
  5. Please contribute your corrections to the db file so others can benefit. Either do a GitHub pull request if you know how, or just send me a quick message at Thanks!
  1. Wait for the board to turn up and solder all your thru-hole and other additional components.

The board I’ve decided to test this on is a ESP32-based WiFi 8 channel PWM controller with a USB-UART adapter IC (Silicon Labs CP2104) and a few auxiliary sensor inputs. On a 6x5cm 4-layer board (mostly screw terminals). I probably could have made it 2-layer if I really wanted, but given how cheap JLC’s 4 layer boards are, I decided to use it as an exercise to see how small I can make the board, with nice power and ground planes. I used a QFN USB interface chip (I probably wouldn’t have if I was soldering this by hand) and plenty of 0402 passives. There are about 50 assembled parts in total per board. The only parts they couldn’t assemble are the ESP32 module, and all the connectors. They should all be pretty easy to hand solder and I am happy that I don’t need to order and organise storage for all those different jellybean components.

The whole thing came to $72.17 before shipping. Including 10x 4 layer boards, $27.51 worth of ~500 components (total for 10 boards), and assembly. How amazing is that?

A bare 4 layer board would have costed more than that just a few years ago.

If I really optimised it for cost by squeezing it into 2 layers and soldering it myself, I probably could have gotten it for maybe $30 less. But it would have taken a few more hours of my time at the very least. Is that a worthwhile trade-off? For me, trading $30 for a few hours of my time is a no-brainer.

If you are a hobbyist who still gets pleasure from soldering, maybe the service isn’t useful to you, but I’ve soldered enough TQFP FPGAs by hand in my life that I’m very happy to let someone else do the soldering, so I can focus on more interesting bits. Especially when that someone else is a machine that can solder much better than I can by hand.


8 days from order to delivery to London, UK, using their DHL shipping option ($19.36). This is a 4 layer board, and they say 2 layer boards should be a few days faster. They also have a nifty progress checker on their orders page.

Quality-wise, there’s really nothing I can nitpick. It’s perfect. The QFN and all the 0402s all look amazing, and no reflow solder residue (tiny solder balls) anywhere. There is some extra solder on the ESP32’s unsoldered pads, but that’s typical of HASL process, and those pads were not reflowed. It also looks much worse in the picture than in real life. They are pretty flat in real life, but of course if you are doing BGA you should opt for ENIG finish for better co-planarity (they offer that for about $20 extra).

I am totally blown away and will be using this service a lot more in the future. No more soldering millions of simple components!

Happy making!



    • I made a mistake (used a version of the regulator with the wrong pinout), and it did work once I replaced that and added all the other components.

  1. Thanks for these scripts. They can be very useful.

    When placing an order, I get to the point where I should see the mock-up with components to be placed (point 9 in your article) but not a single component is shown. The bare PCB is shown.

    I’ve also tried uploading your test board and BOM and CPL with the same result.

    Also tried different browses without luck.

    Is there anything broken at JLCPCB? Am I doing anything wrong?


    • I actually just ran into this issue myself. I contacted their support with my files, and they said there’s nothing wrong with my files, and it’s probably a problem on their end.

      They said if you place the order anyways, at some point on the order details page there will be a “DFM Analysis” link that should let you verify. But I don’t see it on my last order, so I’m not sure.

      I would contact their support with your files just in case.

  2. Thanks for writing this and making your scripts. Using these, I just placed my first SMT assembly order at JLCPBC and am also amazed by how cheap and fast the service is.

  3. Thanks a lot for your scripts. You definitly allows me to have the assembly of my hobby project by JLCPCB. It worked like a charm once I understood the naming constraints on file names (I had different folder names than project names).

    I still have some worry about the diodes and LED orientation. I don’t know if JLCPCB standard orientation for those is OK or not, and what is the meaning of “+” and “-” compared to Anode and Cathode. If you know and could clarify, I would be grateful.


  4. your script gives negative rotations for some parts, e.g. -135, -90, yet the example position file from jlcpcb has all positive rotations, e.g. 270, 90, 0. would it be possible for you to subtract each negative rotation from 360?

    • The script actually already does that for rotations it fixes, so I’m guessing the negative rotations are from parts the script didn’t touch?

      I can make it change all rotations to positive if necessary. Is it causing problems?

      • I haven’t checked the datasheets yet, but everything matched the silkscreen labels, except for an atmega32u4-au. that needed to be rotated 90 degrees clockwise. i think there’s no need to change the negative rotations when it works, i just thought it was a bug.

  5. Hi Matthew, Thanks for making the effort to share this bit of work. I’m a python weeny, and I’m making some trivial mistake I can’t fathom. Duh!

    C:\Users\lamming\Dropbox\KiCad\Irrigator>python Irrigator
    Traceback (most recent call last):
    File “”, line 22, in
    from jlc_lib.cpl_fix_rotations import ReadDB, FixRotations
    ImportError: No module named jlc_lib.cpl_fix_rotations

    I have put everything, code, project files, gerbers etc into the same directory to obviate path errors.

  6. I think it should be mentioned that kicad directories have the same filename as the files within or the script fails. I had that issue due to multiple versions and backups.

  7. Python 3.8.2
    File “”, line 26, in
    from jlc_kicad_tools.jlc_lib.cpl_fix_rotations import ReadDB, FixRotations
    ModuleNotFoundError: No module named ‘jlc_kicad_tools’

    • You need to keep the directory structure, and run the script in the directory containing

      • Hi, I’m facing the same issue as Krzych here… I’m on the same directory and I haven’t changed the directory structure. If I write python3 instead of python at the beginning the script doesn’t output anything at all.

  8. Thanks for this. I just noticing on JLBPCP DFM that several components of mine were rotated and they rotated them to fix it. Any idea why that happens? It’s difficult to use the only gerber viewer to figure out which orientation is correct since you basically have to know which traces are connected to which pins. Also I saw you used a tactile switch – do you know what footprint that is to make it with the ones JLCPCB has, or did you make it yourself? Thanks.

    • Hi Duane,

      If the components were rotated, you need to edit the component list accompanying the script to fix that, as the post describes. JLC will fix them for you if they can, but it’s not guaranteed (and obviously not if they can’t figure out polarity, etc).

      Their gerber viewer should also tell you where pin 1 is, so you can match that to your design to figure out the correct rotation.

      I made the switch footprint myself from the datasheet. Here is the footprint if you want to use it:

      • I started trying to make my own component, but I couldn’t figure out how JLC would know where to put the SMD component – is it just visual, i.e. trying to line up the pads? I thought there might have to be some internal reference point for 0,0 to make that work, but wasn’t sure.

        Do you know why there is a difference between JLC and Kicad for some components? Seems like there is a disconnect somewhere for that to happen. Thanks.

        • I believe (0, 0) is always the centre of the footprint (average of all the pads), but I’m not sure. If in doubt, it’s probably good to make sure that’s the case when you draw your own footprint. It has to be that way because otherwise rotation around (0, 0) wouldn’t work.

          Difference in rotation? No idea. There are probably different systems to determine the “canonical” rotation, and it seems like they use different reference systems.

  9. Hi Matthew,
    Thanks for your awesome work and manual. Looks like this is the last final step before I am ready to order my assembled PCB’s from JLCPCB.
    I followed the manual and installed Python (tried both a Mac with Catalina and Windows 10) but unfortunately do not get beyond step “Run my script and give it the project directory.”
    I do to the directory that has the and the unmodified jlc_lib directory.
    It also contains all the files I exported in the previous steps. Both in the same folder and in a subdirectory ChargeLink.
    Then I run “sudo python Chargelink”
    And after entering my password I get:
    Traceback (most recent call last):
    File “”, line 26, in
    from jlc_kicad_tools.jlc_lib.cpl_fix_rotations import ReadDB, FixRotations
    ImportError: No module named jlc_kicad_tools.jlc_lib.cpl_fix_rotations”
    So is seems it cannot find the jlc_lib folder and it’s contents but it is 100% sure there.
    Hope you have any suggestion on how to proceed.
    On Windows I do no get any message back.
    Using python or python3 is neither successful.
    Thanks in advance,

    • Hi Lars,

      Sorry we changed the directory structure and I forgot to update instructions on my blog post. Please follow the instructions here instead:

      There are currently no instruction for installing pip on Mac, but there should be many tutorials online for that.

      PS. there is no need to run with sudo, and using sudo may mess up the permission of some of your files.


Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.