MIT licensed, fully updated, actively maintained Rust bindings for the KiCAD IPC API
Go to file
Milind Sharma d9644312ef
refactor: modularize client API and finalize v10 assessment follow-ups (#25)
* feat: bump vendored KiCad protos to v10.0.0

* test: add protocol contract tests for board layer name

* docs: overhaul README and guide site

- Rewrite README with punchy opening, realistic examples, and cleaner structure
- Update status to Beta and version numbers to 0.4.1
- Remove redundant sections (roadmap, future work, guide site link)
- Simplify API matrix by removing redundant Status column
- Add CONTRIBUTING.md header with welcoming message
- Expand mdBook examples with real-world patterns:
  - PCB analysis (unconnected nets, footprints)
  - Automation (text variables, test points)
  - CI/CD integration patterns
  - Net class validation
  - Selection manipulation
- Update mdBook intro with comparison table and clearer goals
- Update quickstart version numbers
- Suppress missing_docs warnings for internal modules (commands, envelope, transport)
- Format code with cargo fmt

* docs: complete library assessment report with verified findings

- Corrected baseline metrics (5448 LOC client.rs, 7903 non-generated total, 12766 overall)
- Added full non-generated source tree with LOC breakdown
- Expanded anti-pattern scan from 3 to 6 findings (AP-4 through AP-6)
- Added verified clean signals (zero production unwrap/expect/panic)
- Added transport architecture, feature flag, and model cross-dependency analysis
- Proposed concrete client.rs domain split into 8 modules
- Identified 5 new documentation issues (DR-2 through DR-6)
- Resolved DR-1 (version drift already fixed)
- Expanded risk register from 5 to 9 entries
- Updated prioritized action plan with corrected priorities

* fix: complete P0 action items from library assessment

- Fix clone_on_copy in client.rs map_text_shape (AP-1)
- Add clippy::enum_variant_names allow for generated proto code (AP-2)
- Fix bool_assert_comparison patterns in test assertions (AP-3)
- Fix broken README anchor in validation.md (DR-2)
- Remove docs/book/src/https: filesystem artifact (DR-3)

* refactor: split monolithic client.rs into domain modules

Split src/client.rs (5448 LOC) into src/client/ directory with 11 modules:
- mod.rs: core structs, builder, constants, send_command
- common.rs: ping, version, paths, documents, text vars, text geometry
- board.rs: nets, layers, origin, stackup, graphics, appearance, DRC
- selection.rs: get/add/remove/clear selection
- items.rs: CRUD, get by type/net/class, commit workflow
- document.rs: title block, save, revert, string serialization
- geometry.rs: bounding boxes, hit test, pad polygons, padstack, zones
- mappers.rs: all proto-to-model and model-to-proto conversions
- decode.rs: PCB item type decoding
- format.rs: selection detail formatting, debug utilities
- tests.rs: all unit tests

No public API changes. All existing tests pass.
Updated blocking parity test to scan split module files.

* refactor: add rpc! dispatch macro to reduce RPC boilerplate

Introduce rpc! macro in client/mod.rs that encapsulates the
pack → send_command → response_payload_as_any pattern repeated
across 57 RPC methods. Demonstrate usage in common.rs with 4
converted _raw methods.

* feat: complete P1/P2 action items from library assessment

- Add beginner examples: hello_kicad.rs and board_inspector.rs
- Add README prerequisites section with KiCad IPC API setup guide
- Add README examples section with run commands for all 3 examples
- Add protocol-contract tests: CMD/RES prefix validation, PCB types catalog
- Add module-level rustdoc to all client submodules
- All tests pass (default + blocking features)

* docs: update assessment report with completed action items

Mark resolved: AP-1/AP-2/AP-3 (clippy), DR-2 (anchor), DR-3 (artifact),
ST-1 (client.rs split), DR-5 (examples), DR-6 (prerequisites).
Mark mitigated: AP-4 (RPC boilerplate via rpc! macro).
Update baseline metrics to reflect 11-module client layout.
Update risk register, action plan status, and revision history.

* chore: finalize tier-1 API docs and modular client cleanup

Document the public client and blocking surfaces so strict rustdoc linting passes, while keeping tier-2/3 internals lightly scoped. Also clean stale modularization references and remove leftover split-refactor dead imports/helpers to reduce maintenance drift.
2026-03-29 20:54:49 +08:00
.github/workflows docs: add mdBook guide site and Pages deploy workflow (#15) 2026-02-28 13:15:33 +08:00
docs refactor: modularize client API and finalize v10 assessment follow-ups (#25) 2026-03-29 20:54:49 +08:00
examples refactor: modularize client API and finalize v10 assessment follow-ups (#25) 2026-03-29 20:54:49 +08:00
kicad@0feeca2a80 feat: bump vendored KiCad protos to v10.0.0 (#23) 2026-03-29 12:01:16 +08:00
scripts chore: add proto regeneration maintainer workflow 2026-02-21 00:54:36 +08:00
src refactor: modularize client API and finalize v10 assessment follow-ups (#25) 2026-03-29 20:54:49 +08:00
test-scripts feat: bump vendored KiCad protos to v10.0.0 (#23) 2026-03-29 12:01:16 +08:00
tools/proto-gen chore: add proto regeneration maintainer workflow 2026-02-21 00:54:36 +08:00
.gitignore fix(ci): narrow book ignore to unblock release-plz 2026-03-02 19:58:38 +08:00
.gitmodules chore: add proto regeneration maintainer workflow 2026-02-21 00:54:36 +08:00
AGENTS.md docs: add contributing and repo agent guidance (#9) 2026-02-22 21:20:21 +08:00
CHANGELOG.md chore: release v0.4.2 (#24) 2026-03-29 12:02:21 +08:00
CONTRIBUTING.md feat: bump vendored KiCad protos to v10.0.0 (#23) 2026-03-29 12:01:16 +08:00
CONTRIBUTIONS.md chore: add proto regeneration maintainer workflow 2026-02-21 00:54:36 +08:00
Cargo.lock chore: release v0.4.2 (#24) 2026-03-29 12:02:21 +08:00
Cargo.toml chore: release v0.4.2 (#24) 2026-03-29 12:02:21 +08:00
LICENSE Initial commit 2026-02-18 21:04:43 +08:00
README.md refactor: modularize client API and finalize v10 assessment follow-ups (#25) 2026-03-29 20:54:49 +08:00
release-plz.toml ci: fix release-plz workflow for auto release on main (#10) 2026-02-22 20:40:05 +08:00
slate.json refactor: modularize client API and finalize v10 assessment follow-ups (#25) 2026-03-29 20:54:49 +08:00

README.md

kicad-ipc-rs

Ask DeepWiki

Control KiCad programmatically from Rust. The most complete, production-ready client for KiCad's IPC API — async-first with full sync support.

  • 100% API coverage (57/57 KiCad v10.0.0 commands)
  • Type-safe PCB item manipulation with ergonomic Rust models
  • Both async and blocking APIs for any application architecture
  • Zero protobuf dependencies for consumers — everything is typed Rust

Status

Beta. All KiCad v10.0.0 API commands are implemented and tested.

  • Async API (default): production-ready with full feature parity
  • Sync/blocking wrapper API (feature = "blocking"): production-ready, uses dedicated Tokio runtime thread

Prerequisites

  • Rust 1.70+ (edition 2021)
  • KiCad 10.0.0+ running with the IPC API enabled
  • The nng transport library is bundled automatically via nng-rs

Enabling the KiCad IPC API

  1. Open KiCad → PreferencesPlugins
  2. Check Enable IPC API
  3. Restart KiCad

The API socket path is auto-detected. Override with KICAD_API_SOCKET if needed.

Usage

Async API (Default)

Add to Cargo.toml:

[dependencies]
kicad-ipc-rs = "0.4.1"
tokio = { version = "1", features = ["macros", "rt"] }

Connect and query KiCad:

use kicad_ipc_rs::KiCadClient;

#[tokio::main(flavor = "current_thread")]
async fn main() -> Result<(), kicad_ipc_rs::KiCadError> {
    let client = KiCadClient::connect().await?;
    
    // Get KiCad version info
    let version = client.get_version().await?;
    println!("Connected to KiCad {}", version.full_version);
    
    // Check if a board is open
    if client.has_open_board().await? {
        // Get all nets in the current board
        let nets = client.get_nets().await?;
        println!("Found {} nets", nets.len());
        
        // Get all tracks on the board
        let tracks = client.get_items_by_type_codes(vec![
            kicad_ipc_rs::PcbObjectTypeCode::new_trace()
        ]).await?;
        println!("Found {} tracks", tracks.len());
    }
    
    Ok(())
}

Sync API (Blocking)

Enable the blocking feature for synchronous applications:

[dependencies]
kicad-ipc-rs = { version = "0.4.1", features = ["blocking"] }
use kicad_ipc_rs::KiCadClientBlocking;

fn main() -> Result<(), kicad_ipc_rs::KiCadError> {
    let client = KiCadClientBlocking::connect()?;
    
    // Get all nets and find unconnected ones
    let nets = client.get_nets()?;
    let unconnected: Vec<_> = nets
        .iter()
        .filter(|n| n.name == "unconnected")
        .collect();
    
    println!("Found {} unconnected nets", unconnected.len());
    Ok(())
}

Making Changes to PCBs

All board modifications use commit sessions for safety:

use kicad_ipc_rs::{KiCadClient, CommitAction};

async fn add_track(client: &KiCadClient) -> Result<(), kicad_ipc_rs::KiCadError> {
    // Start a commit session
    let commit = client.begin_commit().await?;
    
    // Create items (tracks, vias, footprints, etc.)
    let items = vec![/* your PcbItem instances */];
    let created_ids = client.create_items(items).await?;
    
    // Commit the changes
    client.end_commit(
        commit.id,
        CommitAction::Commit,
        "Added new track"
    ).await?;
    
    Ok(())
}

Examples

Run the included examples against a running KiCad instance:

# Minimal connection + version check
cargo run --example hello_kicad --features blocking

# Inspect board nets, layers, and origin
cargo run --example board_inspector --features blocking

# Deep-dive into current PCB selection
cargo run --example selection_deep_dump --features blocking

See the examples/ directory for full source.

KiCad Version Compatibility

This crate tracks KiCad releases. When KiCad updates their API, we update within a week. Currently supports KiCad 10.0.0.

KiCad v10.0.0 API Reference

All 57 KiCad v10.0.0 API commands are implemented:

Section Coverage

Section Commands Coverage
Common (base) 6 100%
Common editor/document 23 100%
Project manager 5 100%
Board editor (PCB) 23 100%
Total 57 100%

Command Reference

Common (base)

KiCad Command Rust API
Ping KiCadClient::ping
GetVersion KiCadClient::get_version
GetKiCadBinaryPath KiCadClient::get_kicad_binary_path
GetTextExtents KiCadClient::get_text_extents
GetTextAsShapes KiCadClient::get_text_as_shapes
GetPluginSettingsPath KiCadClient::get_plugin_settings_path

Common editor/document

KiCad Command Rust API
RefreshEditor KiCadClient::refresh_editor
GetOpenDocuments KiCadClient::get_open_documents, get_current_project_path, has_open_board
SaveDocument KiCadClient::save_document
SaveCopyOfDocument KiCadClient::save_copy_of_document
RevertDocument KiCadClient::revert_document
RunAction KiCadClient::run_action
BeginCommit / EndCommit KiCadClient::begin_commit, end_commit
CreateItems KiCadClient::create_items
GetItems KiCadClient::get_items_by_type_codes, get_all_pcb_items, get_pad_netlist
GetItemsById KiCadClient::get_items_by_id
UpdateItems KiCadClient::update_items
DeleteItems KiCadClient::delete_items
GetBoundingBox KiCadClient::get_item_bounding_boxes
GetSelection KiCadClient::get_selection, get_selection_summary, get_selection_details
AddToSelection / RemoveFromSelection / ClearSelection KiCadClient::add_to_selection, remove_from_selection, clear_selection
HitTest KiCadClient::hit_test_item
GetTitleBlockInfo KiCadClient::get_title_block_info
SaveDocumentToString KiCadClient::get_board_as_string
SaveSelectionToString KiCadClient::get_selection_as_string
ParseAndCreateItemsFromString KiCadClient::parse_and_create_items_from_string

Project manager

KiCad Command Rust API
GetNetClasses / SetNetClasses KiCadClient::get_net_classes, set_net_classes
ExpandTextVariables KiCadClient::expand_text_variables
GetTextVariables / SetTextVariables KiCadClient::get_text_variables, set_text_variables

Board editor (PCB)

KiCad Command Rust API
GetBoardStackup / UpdateBoardStackup KiCadClient::get_board_stackup, update_board_stackup
GetBoardEnabledLayers / SetBoardEnabledLayers KiCadClient::get_board_enabled_layers, set_board_enabled_layers
GetGraphicsDefaults KiCadClient::get_graphics_defaults
GetBoardOrigin / SetBoardOrigin KiCadClient::get_board_origin, set_board_origin
GetNets KiCadClient::get_nets
GetItemsByNet / GetItemsByNetClass KiCadClient::get_items_by_net, get_items_by_net_class
GetNetClassForNets KiCadClient::get_netclass_for_nets
RefillZones KiCadClient::refill_zones
GetPadShapeAsPolygon KiCadClient::get_pad_shape_as_polygon
CheckPadstackPresenceOnLayers KiCadClient::check_padstack_presence_on_layers
InjectDrcError KiCadClient::inject_drc_error
GetVisibleLayers / SetVisibleLayers KiCadClient::get_visible_layers, set_visible_layers
GetActiveLayer / SetActiveLayer KiCadClient::get_active_layer, set_active_layer
GetBoardLayerName KiCadClient::get_board_layer_name
GetBoardEditorAppearanceSettings / SetBoardEditorAppearanceSettings KiCadClient::get_board_editor_appearance_settings, set_board_editor_appearance_settings
InteractiveMoveItems KiCadClient::interactive_move_items

Documentation

Protobuf Source

This crate ships checked-in Rust protobuf output under src/proto/generated/.

  • Consumers do not need KiCad source checkout or git submodules
  • Maintainers regenerate bindings from KiCad upstream via the kicad git submodule
  • Current proto pin: KiCad 10.0.0 (KICAD_API_VERSION = 10.0.0-0-g0feeca2a)

Maintainer refresh flow:

git submodule update --init --recursive
./scripts/regenerate-protos.sh

Contributing

See CONTRIBUTING.md for development workflow and commit conventions.

Issues and PRs welcome!

License

MIT