npnp
Languages: English | Chinese
Normalize Pin Net Pad (npnp) is an LCEDA/EasyEDA downloader and Altium library exporter written in pure Rust.
npnp searches LCEDA/LCSC components, downloads upstream EasyEDA source data and 3D models, and exports Altium-compatible schematic and PCB footprint libraries.
Features
- Search LCEDA/LCSC components by keyword, part name, or LCSC ID.
- Download 3D models as STEP or OBJ/MTL.
- Export raw EasyEDA symbol and footprint JSON for inspection.
- Export Altium schematic libraries (
.SchLib). - Export Altium PCB footprint libraries (
.PcbLib). - Embed STEP models into PCB libraries when upstream STEP data is available.
- Batch export many LCSC IDs from a text file.
- Export either one file per component or merged library pairs.
- Resume non-merged batch exports with checkpoint files.
- Retry transient LCEDA/EasyEDA request failures automatically.
Requirements
- Rust toolchain for building from source.
- Network access to LCEDA/EasyEDA APIs when searching, downloading, or exporting.
- Altium Designer is recommended for final visual verification of generated
.SchLiband.PcbLibfiles.
Install Rust from https://rustup.rs/ if you do not already have it.
Build From Source
Clone the repository:
git clone https://github.com/linkyourbin/npnp.git npnp
cd npnp
Build a debug binary:
cargo build
Build an optimized release binary:
cargo build --release
Run the test suite:
cargo test
Run formatting before publishing or sending a pull request:
cargo fmt
Run a compile check without producing a release binary:
cargo check
Run From Source
When running through Cargo, put -- before npnp arguments:
cargo run --quiet --bin npnp -- --help
Show ready-to-run examples:
cargo run --quiet --bin npnp -- --prompt
Show the package version:
cargo run --quiet --bin npnp -- --version
Run any command from source:
cargo run --quiet --bin npnp -- <COMMAND> [OPTIONS]
Example source-run search:
cargo run --quiet --bin npnp -- search C2040 --limit 5
Run As A Binary
After cargo build --release, the Windows binary is:
.\target\release\npnp.exe
Show help from the built binary:
.\target\release\npnp.exe --help
Show ready-to-run command examples:
.\target\release\npnp.exe --prompt
Show the version:
.\target\release\npnp.exe --version
Run a command with the built binary:
.\target\release\npnp.exe <COMMAND> [OPTIONS]
If npnp.exe is on your PATH, use it directly:
npnp --help
npnp --prompt
npnp search C2040 --limit 5
Install Locally
Install the current checkout as a local Cargo binary:
cargo install --path .
Verify the installed binary:
npnp --version
Uninstall the local Cargo-installed binary:
cargo uninstall npnp
The tool is published to crates.io. Users with a Rust development environment can install it with:
cargo install npnp
Command Overview
Top-level help:
npnp --help
Ready-to-run examples:
npnp --prompt
Help for a specific command:
npnp <COMMAND> --help
Available commands:
searchdownload-stepdownload-objexport-sourceexport-schlibexport-pcblibbundlebatch
Command: search
Search components by keyword, LCSC ID, manufacturer part, or broad text.
Usage:
npnp search <KEYWORD> [--limit <LIMIT>]
Examples:
npnp search C2040 --limit 5
npnp search RP2040 --limit 10
npnp search TYPE-C --limit 20
Options:
--limit <LIMIT>controls how many search rows are printed. Default:20.
Output includes the search result index, display name, LCSC ID when available, manufacturer, and whether a 3D model is listed.
Search Result Indexes
Most export/download commands accept --index <INDEX>. The default is --index 1.
Use this workflow for broad searches:
npnp search TYPE-C --limit 20
Then export the exact row you want:
npnp export-schlib TYPE-C --index 3 --output schlib --force
When <KEYWORD> is an exact LCSC ID like C2040 and --index is left at 1, npnp prefers the search result whose LCSC ID exactly matches the keyword. Explicit non-default indexes still select the requested search row.
Command: download-step
Download a STEP file for the selected component result.
Usage:
npnp download-step <KEYWORD> [--index <INDEX>] [--output <DIR>] [--force]
Examples:
npnp download-step C2040 --output step --force
npnp download-step RP2040 --index 1 --output models\step --force
Options:
--index <INDEX>selects the search result row. Default:1.--output <DIR>sets the output directory. Default:step.--forceoverwrites an existing output file.
Typical output layout:
step/
<footprint-or-component-name>.step
Command: download-obj
Download OBJ and MTL files for the selected component result.
Usage:
npnp download-obj <KEYWORD> [--index <INDEX>] [--output <DIR>] [--force]
Examples:
npnp download-obj C2040 --output obj --force
npnp download-obj RP2040 --index 1 --output models\obj --force
Options:
--index <INDEX>selects the search result row. Default:1.--output <DIR>sets the output directory. Default:obj.--forceoverwrites existing OBJ/MTL files.
Typical output layout:
obj/
<component-name>.obj
<component-name>.mtl
Command: export-source
Export raw EasyEDA symbol and footprint source JSON files only.
Use this command when you want to inspect upstream payloads before generating Altium libraries.
Usage:
npnp export-source <KEYWORD> [--index <INDEX>] [--output <DIR>] [--force]
Examples:
npnp export-source C2040 --output easyeda_src --force
npnp export-source RP2040 --index 1 --output debug\easyeda_src --force
Options:
--index <INDEX>selects the search result row. Default:1.--output <DIR>sets the output directory. Default:easyeda_src.--forceoverwrites existing source JSON files.
Typical output layout:
easyeda_src/
<component-name>_symbol_easyeda.json
<component-name>_footprint_easyeda.json
Command: export-schlib
Export a pure Rust Altium schematic library (.SchLib).
Usage:
npnp export-schlib <KEYWORD> [--index <INDEX>] [--output <DIR>] [--force]
Examples:
npnp export-schlib C2040 --output schlib --force
npnp export-schlib RP2040 --index 1 --output out\schlib --force
Options:
--index <INDEX>selects the search result row. Default:1.--output <DIR>sets the output directory. Default:schlib.--forceoverwrites an existing.SchLibfile.
Current schematic export includes:
- Symbol body and graphics.
- Pins.
- Multipart symbols when present in source data.
- Metadata records such as
Designator,Comment,Description, and parameters. - PCB footprint implementation links when footprint data is available.
Typical output layout:
schlib/
<component-name>.SchLib
Command: export-pcblib
Export a pure Rust Altium PCB footprint library (.PcbLib).
Usage:
npnp export-pcblib <KEYWORD> [--index <INDEX>] [--output <DIR>] [--force]
Examples:
npnp export-pcblib C2040 --output pcblib --force
npnp export-pcblib RP2040 --index 1 --output out\pcblib --force
Options:
--index <INDEX>selects the search result row. Default:1.--output <DIR>sets the output directory. Default:pcblib.--forceoverwrites an existing.PcbLibfile.
Current PCB export includes:
- Pads.
- Tracks, arcs, regions, and footprint primitives mapped from EasyEDA data.
- 3D STEP model embedding when a usable upstream STEP model exists.
- Empty 3D body output when no usable STEP model is available.
Typical output layout:
pcblib/
<component-name>.PcbLib
Command: bundle
Export a source bundle for one selected component.
The bundle command writes EasyEDA source JSON files, a STEP file when available, and a manifest JSON file that records the selected component and generated artifacts.
Usage:
npnp bundle <KEYWORD> [--index <INDEX>] [--output <DIR>] [--force]
Examples:
npnp bundle C2040 --output bundle --force
npnp bundle RP2040 --index 1 --output out\bundle --force
Options:
--index <INDEX>selects the search result row. Default:1.--output <DIR>sets the output directory. Default:bundle.--forceoverwrites existing bundle files.
Typical output layout:
bundle/
<component-name>_symbol_easyeda.json
<component-name>_footprint_easyeda.json
<footprint-or-component-name>.step
<component-name>_bundle.json
The STEP file appears only when the selected component has an upstream 3D model.
Command: batch
Batch export Altium libraries from a text file containing LCSC IDs.
Usage:
npnp batch --input <FILE> [--output <DIR>] [--schlib] [--pcblib] [--full] [--merge] [--library-name <NAME>] [--parallel <N>] [--continue-on-error] [--force]
Short input flag:
npnp batch -i ids.txt --output batch_out --full --force
The input parser extracts IDs in the form C<number> from arbitrary text. It accepts lowercase IDs like c2040, deduplicates repeated IDs, and preserves first-seen order.
Example ids.txt:
C2040
C12074
C569043
Export both schematic and PCB libraries, one file per component:
npnp batch --input ids.txt --output batch_out --full --parallel 4 --continue-on-error --force
Export only schematic libraries:
npnp batch --input ids.txt --output batch_schlib --schlib --parallel 4 --continue-on-error --force
Export only PCB libraries:
npnp batch --input ids.txt --output batch_pcblib --pcblib --parallel 4 --continue-on-error --force
Export both targets using explicit flags instead of --full:
npnp batch --input ids.txt --output batch_out --schlib --pcblib --parallel 4 --continue-on-error --force
Write one merged .SchLib and one merged .PcbLib:
npnp batch --input ids.txt --output merged_out --merge --library-name MyLib --full --continue-on-error --force
Write only a merged schematic library:
npnp batch --input ids.txt --output merged_schlib --merge --library-name MySchLib --schlib --continue-on-error --force
Write only a merged PCB library:
npnp batch --input ids.txt --output merged_pcblib --merge --library-name MyPcbLib --pcblib --continue-on-error --force
Batch options:
--input <FILE>or-i <FILE>is required.--output <DIR>sets the output directory. Default:batch.--schlibexports schematic libraries.--pcblibexports PCB libraries.--fullexports both schematic and PCB libraries.--mergewrites one merged library per selected target instead of one file per component.--library-name <NAME>sets the merged output filename prefix.--parallel <N>sets concurrent jobs for non-merged batch export. Default:4.--continue-on-errorkeeps processing remaining IDs if one ID fails.--forceignores checkpoint skips and overwrites existing outputs.
Non-merged batch output layout:
batch_out/
.checkpoint
schlib/
<component-a>.SchLib
<component-b>.SchLib
pcblib/
<component-a>.PcbLib
<component-b>.PcbLib
Merged batch output layout:
merged_out/
MyLib.SchLib
MyLib.PcbLib
Checkpoint behavior:
- Non-merged batch exports create
.checkpointin the output directory. - Completed IDs are written to
.checkpoint. - Later runs skip completed IDs unless
--forceis used. - Merged batch exports rebuild the merged output and do not use the non-merged checkpoint layout.
Recommended Workflows
Exact LCSC ID workflow:
npnp search C2040 --limit 5
npnp export-schlib C2040 --output out\schlib --force
npnp export-pcblib C2040 --output out\pcblib --force
Broad keyword workflow:
npnp search TYPE-C --limit 20
npnp export-schlib TYPE-C --index 3 --output out\schlib --force
npnp export-pcblib TYPE-C --index 3 --output out\pcblib --force
Source inspection workflow:
npnp export-source C2040 --output inspect\easyeda --force
npnp bundle C2040 --output inspect\bundle --force
Batch verification workflow:
npnp batch --input ids.txt --output generated\check --full --force --continue-on-error
Merged library verification workflow:
npnp batch --input ids.txt --output generated\merged_check --merge --library-name MyLib --full --force --continue-on-error
Merge Output Screenshots
The imgs/ directory stores screenshots generated from merged-library output produced by npnp.
These examples come from a merged export workflow such as:
npnp batch --input ids.txt --output generated\merged_check --merge --library-name MyLib --full --force --continue-on-error
Overview:

Schematic library screenshots:
PCB library screenshots:
License
npnp now uses the closest standard license to the current project intent: PolyForm-Noncommercial-1.0.0 in LICENSE.txt.
- Non-commercial use, research, evaluation, and personal experimentation are allowed.
- Commercial use, paid redistribution, paid service use, or use inside a commercial workflow requires separate permission from the author.
- If you redistribute the project, keep the license text and required notices.
- The PolyForm license does not legally require pull requests. This project still asks anyone publishing modified versions to mention the original
npnpproject and, when possible, send changes back as a pull request. - This is source-available and non-commercial, not an OSI open-source license.
Notes On Generated Files
- Output filenames are sanitized for Windows-unsafe characters.
- Existing files are preserved unless
--forceis passed. - STEP embedding depends on upstream LCEDA/EasyEDA model availability and payload quality.
- If a footprint opens without a 3D body, the upstream STEP model may be missing, invalid, or not linked from the selected component.
- The generated libraries should be opened in Altium Designer for final visual verification before production use.
Troubleshooting
No valid IDs found in batch input:
npnp batch --input ids.txt --output batch_out --full
Check that ids.txt contains values like:
C2040
C12074
C569043
Wrong component exported from a broad keyword:
npnp search <KEYWORD> --limit 20
Then pass the desired result row:
npnp export-schlib <KEYWORD> --index <ROW> --output schlib --force
Existing output was not overwritten:
npnp export-pcblib C2040 --output pcblib --force
Resume or rerun a non-merged batch export:
npnp batch --input ids.txt --output batch_out --full --continue-on-error
Force a full non-merged batch rebuild:
npnp batch --input ids.txt --output batch_out --full --force --continue-on-error
Network/API issues:
- Confirm that the machine can reach LCEDA/EasyEDA APIs.
- Retry later if LCEDA/EasyEDA is temporarily unavailable.
npnpautomatically retries transient request failures such as timeouts, connection failures, rate limiting, and server-side5xxresponses.