kicad10-to-altium
Public Unreviewedby barrett-land
Import KiCad 10 symbols into Altium Designer correctly. Altium 26 supports KiCad through 9 only, so a raw KiCad 10 import silently loses property visibility and every hidden field lands visible. Downgrades v10 to v9 first, then imports headlessly, links the footprint, and repairs visibility.
Install?
Import KiCad 10 symbols into Altium Designer correctly. Altium 26 supports KiCad through 9 only, so a raw KiCad 10 import silently loses property visibility and every hidden field lands visible. Downgrades v10 to v9 first, then imports headlessly, links the footprint, and repairs visibility.
adom-wiki pkg install barrett-land/kicad10-to-altium
Latest: v1.5.0, published
Dependencies 1 app
Contents
README
markdownkicad10-to-altium
SUPERSEDED (2026-08-30): this functionality now lives in adom/altium-bridge — the master Altium bridge + skillpack, maintained by the adom org. Install the skillpack instead:
adom-wiki pkg install adom/altium-bridge(skill: altium-kicad-import; the v10→v9 downgrader ships in its tools/). This page stays up for existing installs but receives no further updates.
Get KiCad symbols into Altium Designer correctly — especially from KiCad 10.

The problem
Altium 26's KiCad importer understands the format through KiCad 9. A KiCad 10 file still imports, but silently drops property visibility — so every field that is hidden in KiCad lands visible in Altium, stacking into an unreadable pile on top of the symbol.
Measured on the same Device:R symbol from each installed KiCad:
| Source | Importer warnings | Hidden preserved |
|---|---|---|
| KiCad 8 | 1 | 5 ✓ |
| KiCad 9 | 2 | 5 ✓ |
| KiCad 10 | 7 | 0 ✗ |
| KiCad 10 → 9 (this skill) | 2 | 5 ✓ |
Pins and body geometry survive in every case. It is the metadata that degrades.
KiCad 9 cannot open a KiCad 10 library at all (Unable to load library), so there is no
"re-save it in KiCad 9" escape hatch for a v10-only third-party library. Hence the converter.
Use it
python3 kicad_v10_to_v9.py in.kicad_sym -o out_v9.kicad_sym
kicad-cli sym export svg out_v9.kicad_sym -o /tmp/svg # must exit 0
Then import headlessly via the AdomBridge extension, link a real footprint model, normalise the
text style with altium_set_text_style, and — for symbols already imported badly — repair
visibility in place with altium_set_visibility.
The other silent difference: font and colour
The importer does not reuse the document's default font. Read straight out of the .SchLib
binary, a hand-made part and an imported one in the same library disagree on every text object:
| Font | Face / size | Color |
|
|---|---|---|---|
| Hand-made Altium part | FontID=1 |
Times New Roman 10 | 8388608 |
| KiCad-imported part | FontID=3 / 4 |
Yu Gothic UI Light 8 | 8650884 |
Altium stores colour as BGR, so 8388608 = $800000 = navy RGB(0,0,128); the imported
8650884 is RGB(4,2,132), just off enough to read as a rendering artefact instead of wrong data.
The importer also appends fonts rather than reusing them, so a library imported into repeatedly
accumulates near-duplicate table entries.
Pins are separate. Pin name and number are properties of the pin, not parameters, each with its
own font mode — so they keep the imported face even after every parameter is fixed. They are also
black in Altium, not navy. altium_set_text_style handles both.
The body is two more colours. KiCad draws passives maroon (#840000, arriving as 132);
Altium draws passives blue (16711680) and IC outlines black. The fill (AreaColor) is separate
again and can arrive maroon with IsSolid=T, a solid block behind a correct outline; Altium's fill
is 11599871, pale yellow.
A normalised import therefore touches four colours: parameter text navy 8388608, pins black
0, body outline blue or black by part type, body fill 11599871. Fix three of four and the part
still looks imported. Outline choice is automatic, keyed on pin count: 2 or fewer is a passive.
Note when verifying: Altium omits Color= when the value is 0, so a graphic record with no
colour key is black, not unset.
Footprints import too
.kicad_mod is absent from the KiCad importer's advertised doc-kind list and imports anyway —
verified as LQFP-48_7x7mm_P0.5mm, 48 pads, courtyard, silkscreen and fab layer intact. Treat that
list as a floor, not a ceiling. Two caveats: the output library is named after the containing
folder (KiCad footprint libs are directories), and all stroke widths are lost to Altium's
10-mil default — KiCad's 0.12 mm silk and 0.05 mm courtyard both land at 0.254 mm.
Stacked power pins
KiCad stacks an IC's repeated power pins at one location and hides all but one (three VSS pins on
an STM32F103). Altium's importer does not understand (hide yes) on a pin — Unknown child hide of pin — so they all arrive visible and their numbers render on top of each other. Hide the same ones
KiCad hid with altium_set_visibility + hidepins; they stay electrically present regardless.
Derived symbols: the failure a token-perfect conversion still hits
KiCad 9 resolves (extends "Base") in a single forward pass, so a derived symbol placed before
its base makes the entire library fail to load. KiCad 10 does not care about order — so v10 files
store the derived symbol first, and real ones do.
kicad-cli reports only Unable to load library, naming neither symbol, on a file that KiCad 10
opens fine. That asymmetry is the diagnostic: loads in 10, fails in 9 means a v9-only rule.
This converter topologically reorders symbols so each base precedes its dependants.
Derived symbols are how KiCad ships most ICs — every part in MCU_ST_STM32F1 is one — so ignoring
order works on passives and fails on practically every real IC.
Why a parser and not a regex
hide is relocated between versions, not renamed: KiCad 9 nests (hide yes) inside
(effects …); KiCad 10 moved it out to be a direct child of property. Substituting the token
in place yields a file that is neither version — KiCad 9 rejects it and Altium ignores the orphan
token, so visibility is still lost while the warning count drops, which looks like success.
See SKILL.md for the full workflow, what downgrading costs, and the operational
gotchas (serial-only verbs, timeouts that actually succeeded, stuck X2.EXE launchers).