tidybom
v1.0.0
Published
Turn any messy electronics BOM into clean, normalized, machine-readable data. CSV/TSV/XLSX in, JSON/CSV out. Deterministic, offline, no account.
Downloads
120
Maintainers
Readme
TidyBOM
Any messy electronics BOM in — clean, normalized, machine-readable data out.
If you've ever tried to do anything programmatic with a Bill of Materials, you know it's where good intentions go to die. Altium exports one shape, KiCad another, then a human "fixes" it in Excel. By the time a BOM reaches you, the header row is on line 7, two columns are merged, quantities live in multi-line cells, the part-number column is called MPN or P/N or Codice or Teilenummer, passive values are written five ways in the same file, and a third of the rows say "do not populate" in a spelling you've never seen.
TidyBOM cleans all of it. It's a deterministic, ten-phase pipeline — no LLM, no cloud, no account — and every transformation is inspectable and testable.
npm install -g tidybom
tidybom messy-export.xlsx -o clean.jsonBefore → after
A real (anonymized) BOM with a title block, Italian headers, value soup, a DNP part, a designator range, and a package string sitting in the quantity column:
Progetto Scheda Alimentatore
Rev,3,Data,2026-01-12
Riferimento,Codice,Produttore,Valore,Package,Q.ta
R1-R3,RC0805FR-0710KL,Yageo,10kΩ,0805,3
C1,GRM188R71C104KA01D,Murata,100nF,0603,1
C2,GRM188R71C104KA01D,Murata,100nF,0603,1
C3,,,,0603,DNP
L1,744043100,Wurth,4u7,1210,"Φ18 x H25 x P7.5 mm"
R4,RC0805FR-074R7L,Yageo,4R7,0805,2$ tidybom bom.csv --csv
refs,quantity,mpn,manufacturer,value,footprint,fitted,description
R1 R2 R3,3,RC0805FR-0710KL,Yageo,10k,0805,yes,
C1 C2,2,GRM188R71C104KA01D,Murata,100nF,0603,yes,
C3,,,,0603,no,
L1,1,744043100,Wurth,4.7µF,1210,yes,
R4,2,RC0805FR-074R7L,Yageo,4.7,0805,yes,
# tidybom: 6 components (1 DNP), header on row 4, 1 warning, 0 errorsNotice what happened: the header row was found under the title block, R1-R3 expanded, the two 100nF lines merged, 10kΩ/4u7/4R7 normalized, the DNP part flagged not-fitted, and Φ18 x H25 x P7.5 mm was not read as a quantity of 18258 (ask me how I know).
What it handles
| Problem | Example | Result |
|---|---|---|
| Header not on row 1 | title block, rev info above | finds the real header |
| Non-standard / multilingual columns | MPN, P/N, Codice, Teilenummer, Cantidad | mapped to canonical fields |
| Designator ranges | R1-R4, R7 | R1 R2 R3 R4 R7 |
| Value soup | 10kΩ, 10K0, 4u7, 4R7 | 10k, 10k, 4.7µF, 4.7 |
| "Do Not Populate" | DNP, do not fit, non montare, nicht bestücken | fitted: false |
| Split lines | same MPN on two rows | merged, quantities summed |
| Quantities that lie | a package string in the qty cell | rejected + flagged, never invented |
Usage
CLI:
tidybom <input> [options]
-o, --out <file> write output to a file (default: stdout)
--csv emit CSV (default: JSON)
--format <fmt> csv | tsv | xlsx | auto (default: auto by extension)
--no-dedupe keep duplicate part numbers
--quiet suppress the stderr summaryLibrary:
const { tidy, toCSV } = require("tidybom");
const fs = require("fs");
const result = tidy(fs.readFileSync("bom.csv"), { format: "csv" });
console.log(result.components); // clean array
console.log(result.flags); // things a human should look at
console.log(result.meta); // header row, column map, countsXLSX support uses the optional xlsx package; CSV/TSV work with zero dependencies. The output schema is documented in docs/format-spec.md.
Why open?
Because BOM cleaning is plumbing, and plumbing should be free and inspectable. Every engineer rebuilds this badly in a spreadsheet macro. One good, MIT-licensed implementation — with a real test suite of horrible real-world BOMs — saves the whole community that twenty minutes, a hundred thousand times over.
Contributing
The most useful thing you can send me is a BOM that breaks it. See CONTRIBUTING.md — anonymized fixtures with expected output are the heart of this project.
License
MIT © Bianca Medeiros. See LICENSE.
TidyBOM is built and maintained by the team behind BOMwise. BOMwise picks up where this leaves off — it takes a clean BOM and suggests cheaper, functionally-equivalent component alternatives. We open-sourced the cleaning layer because every engineer deserves a BOM that parses, whether or not they ever touch our product. (It's free while in beta.) If TidyBOM saved you twenty minutes, star the repo and send me a BOM that breaks it.
