Project Workflows And Read-Path Selection

Purpose

KiCad Monkey has two complementary API families. Full model APIs load typed object graphs for editing, rendering, netlisting, and serialization. Projection and targeted-reader APIs scan source files and hydrate only selected object families for inventories and diagnostics.

Choose the smallest API that preserves the behavior your workflow needs. This guide is user-facing; the durable API contracts remain in the API design docs.

Decision Table

Workflow Use Cost model
Compile a project netlist. KiCadDesign.from_project_file(...) Loads project JSON and schematic hierarchy; does not parse the PCB for schematic-only netlist compilation.
Write design JSON for review or downstream tools. KiCadDesign.from_project_file(...) Loads project JSON and schematic hierarchy; parses the PCB when board-backed design JSON fields are needed.
Edit, write, render, or inspect full PCB geometry. KiCadPcb.from_file(...) Full PCB parse and typed model materialization.
Render PCB SVG or PCB plotter IR. KiCadPcb.to_svg(), KiCadPcb.to_ir(), or KiCadDesign.to_pcb_svg() Full board parse plus full IR construction; layers= filters output after IR construction.
Scan one or two large-board PCB families such as routes, zones, or model references. KiCadPcbProjection.from_file(...) Reads and scans the source file, then hydrates only requested PCB families; best for narrow scans and source spans.
Count several common or nested PCB families such as footprints and pads. Measure both KiCadPcb and KiCadPcbProjection for the workload. Projection can cost as much as or more than a full parse when many families are requested.
Scan one object family from PCB, schematic, symbol, footprint, model, or embedded-file sources. iter_kicad_objects_from_file(...) Generic targeted source scan plus selected object hydration.
Mutate schematic symbols, labels, wires, sheets, or properties. KiCadSchematic.from_file(...) Full schematic parse and typed model materialization.
Scan schematic symbols or other schematic primitives without full netlisting/rendering. iter_kicad_objects_from_file(path, SchSymbol) or another schematic class. Targeted source scan. There is no named KiCadSchematicProjection facade today.

Indicative current measurements on this branch: a 59.6 MB WREN board full parse was about 26.7s, projection route scan about 20.0s, and projection common-family inventory about 32.0s. Treat these as order-of-magnitude anchors for API choice, not release gates. The pattern matters more than the exact number: narrow scans can win; broad or nested inventories can match or exceed full-parse time. PCB render layers= selection does not reduce parse or IR-build cost.

Project-Level Workflows

Use KiCadDesign when the workflow needs cross-document context: netlists, design JSON, hierarchical schematic instances, schematic rendering, PCB rendering, or one object that coordinates project, schematic, and board files.

from kicad_monkey import KiCadDesign
from pathlib import Path

design = KiCadDesign.from_project_file("hardware/demo.kicad_pro")
netlist = design.to_netlist()

Path("build").mkdir(parents=True, exist_ok=True)
design.save_json("build/design.json")

for sheet in design.schematic_instances():
    print(sheet.sheet_name, sheet.sheet_path)

KiCadDesign.from_project_file loads project JSON and the top schematic immediately. The adjacent PCB is parsed lazily when design.pcb, PCB IR, PCB SVG, or design JSON output needs board data. Once PCB data is touched, PCB rendering is still a full-board render path.

PCB Rendering Workflows

Use the full PCB model when a workflow needs render correctness, full geometry, mutation, or write-back. The renderer uses plotter IR as the canonical intermediate representation for PCB SVG output.

from kicad_monkey import KiCadPcb

board = KiCadPcb.from_file("hardware/demo.kicad_pcb")
svg = board.to_svg(layers=["Edge.Cuts", "F.Cu", "F.SilkS"])
board.save("hardware/demo.edited.kicad_pcb")

Layer filtering is an output filter, not a partial parser. The current PCB SVG path computes bounds, builds full plotter IR, and then filters emitted SVG records by layer. Do not use layers= as a performance substitute for projection.

Large PCB Inventory Workflows

Use KiCadPcbProjection for narrow large-board inventories and source-span diagnostics when the workflow does not need mutation, rendering, full-board geometry, or serialization.

from kicad_monkey import KiCadPcbProjection

projection = KiCadPcbProjection.from_file("hardware/demo.kicad_pcb")

route_count = len(projection.segments()) + len(projection.vias())
print("route objects", route_count)

for model_ref in projection.model_references():
    print(model_ref.reference, model_ref.path)

Projection reads and scans source text, so it is not free. It can reduce wall-clock time and memory for narrow family scans by avoiding full typed board materialization. When a workflow requests several common or nested families, projection can cost as much as or more than a full parse; use the full model when that is simpler or when complete board context is needed.

Net inventory needs format awareness. KiCad v10 boards can omit the top-level net table and store name-only net references on objects, so projection.nets() can legitimately be empty even when routed objects reference nets.

Schematic And Generic Targeted Reads

Use the generic targeted reader for narrow object-family scans in schematic, PCB, symbol, footprint, model, and embedded-file sources. The object type must expose a from_sexp factory.

from kicad_monkey import SchSymbol, iter_kicad_objects_from_file

for symbol in iter_kicad_objects_from_file("hardware/demo.kicad_sch", SchSymbol):
    print(symbol.reference, symbol.value)

This is the supported schematic narrow-read path today. Use KiCadSchematic instead when the workflow needs edits, full-object queries, schematic IR, SVG rendering, or netlist semantics.

Repeated Views And Caching

If a workflow renders several views of the same board, keep one loaded KiCadPcb or KiCadDesign object and render from it repeatedly. KiCad Monkey does not currently expose a public render cache API for cross-caller reuse. A public cache would need explicit invalidation, lifetime, mutation, memory, and serialization contracts.

Rules Of Thumb

Related Reference