Documentation Index
Fetch the complete documentation index at: https://mintlify.com/KiCad/kicad-source-mirror/llms.txt
Use this file to discover all available pages before exploring further.
Overview
KiCad provides multiple plugin mechanisms for extending functionality:
- Python Scripting: Action plugins and automation via Python API
- 3D Model Plugins: Import various 3D formats
- I/O Plugins: Support additional file formats
- IPC API: External tool integration via protocol buffers
Python Scripting
Architecture
KiCad uses SWIG (Simplified Wrapper and Interface Generator) to expose C++ classes to Python.
Key files:
scripting/kicadplugins.i - SWIG interface definition
scripting/python_scripting.cpp - Python integration layer
scripting/python_manager.cpp - Plugin lifecycle management
Python API Exposure
SWIG Interface
// From kicadplugins.i
%module pcbnew
%{
#include <board.h>
#include <footprint.h>
#include <pcb_track.h>
%}
%include <board.h>
%include <footprint.h>
%include <pcb_track.h>
Generated bindings:
pcbnew.py - PCB editor API
- Python wrapper for C++ classes
- Automatic memory management via SWIG
Plugin Types
Action Plugins
Location: Loaded from standard plugin directories
- Linux:
~/.local/share/kicad/scripting/plugins/
- Windows:
%APPDATA%/kicad/scripting/plugins/
- macOS:
~/Library/Application Support/kicad/scripting/plugins/
Plugin structure:
import pcbnew
class MyPlugin(pcbnew.ActionPlugin):
def defaults(self):
self.name = "My Plugin"
self.category = "Modify PCB"
self.description = "Does something useful"
self.show_toolbar_button = True
self.icon_file_name = "icon.png"
def Run(self):
board = pcbnew.GetBoard()
# Manipulate board...
pcbnew.Refresh()
MyPlugin().register()
Capabilities:
- Access full board data structure
- Create/modify footprints, tracks, zones
- Read design rules
- Generate manufacturing outputs
- UI integration via toolbar buttons
Purpose: Parametric footprint generation
import pcbnew
import FootprintWizardBase
class ConnectorWizard(FootprintWizardBase.FootprintWizard):
def GetName(self):
return "Connector"
def GetDescription(self):
return "Generates pin header footprints"
def GetValue(self):
pins = self.parameters["Pads"]["count"]
return f"CONN_{pins}"
def GenerateParameterList(self):
self.AddParam("Pads", "count", self.uNatural, 10)
self.AddParam("Pads", "pitch", self.uMM, 2.54)
def BuildFootprint(self):
footprint = pcbnew.FOOTPRINT(None)
# Build parametric footprint...
return footprint
ConnectorWizard().register()
Python Shell Integration
Interactive console: Built into Pcbnew (if KICAD_SCRIPTING_WXPYTHON enabled)
# Access current board
board = pcbnew.GetBoard()
# Iterate over footprints
for fp in board.GetFootprints():
print(f"{fp.GetReference()}: {fp.GetValue()}")
# Modify properties
for track in board.GetTracks():
track.SetWidth(pcbnew.FromMM(0.25))
pcbnew.Refresh()
Python API Examples
Board manipulation
import pcbnew
board = pcbnew.LoadBoard("project.kicad_pcb")
# Get board properties
print(f"Board size: {board.GetBoundingBox()}")
print(f"Layer count: {board.GetCopperLayerCount()}")
# Add a trace
track = pcbnew.PCB_TRACK(board)
track.SetStart(pcbnew.VECTOR2I(pcbnew.FromMM(10), pcbnew.FromMM(20)))
track.SetEnd(pcbnew.VECTOR2I(pcbnew.FromMM(30), pcbnew.FromMM(20)))
track.SetWidth(pcbnew.FromMM(0.2))
track.SetLayer(pcbnew.F_Cu)
board.Add(track)
pcbnew.SaveBoard("modified.kicad_pcb", board)
Netlist processing
def update_component_values(board, reference_map):
"""Update component values based on mapping"""
for fp in board.GetFootprints():
ref = fp.GetReference()
if ref in reference_map:
fp.SetValue(reference_map[ref])
values = {"R1": "10k", "R2": "22k", "C1": "100nF"}
update_component_values(board, values)
wxPython Integration
Requires: KICAD_SCRIPTING_WXPYTHON=ON (default)
Purpose: Create custom UI dialogs
import wx
import pcbnew
class ConfigDialog(wx.Dialog):
def __init__(self, parent):
wx.Dialog.__init__(self, parent, title="Plugin Config")
panel = wx.Panel(self)
sizer = wx.BoxSizer(wx.VERTICAL)
self.text = wx.TextCtrl(panel)
sizer.Add(self.text, 0, wx.EXPAND | wx.ALL, 5)
btn = wx.Button(panel, label="OK")
btn.Bind(wx.EVT_BUTTON, self.OnOK)
sizer.Add(btn, 0, wx.ALL, 5)
panel.SetSizer(sizer)
def OnOK(self, event):
self.EndModal(wx.ID_OK)
class UIPlugin(pcbnew.ActionPlugin):
def Run(self):
dlg = ConfigDialog(None)
if dlg.ShowModal() == wx.ID_OK:
# Use dlg.text.GetValue()
pass
dlg.Destroy()
3D Model Plugins
Overview
3D plugins enable importing various 3D model formats into KiCad’s 3D viewer.
Location: plugins/3d/
STEP (via OpenCASCADE)
Plugin: plugins/3d/oce/
Features:
- Industry-standard CAD format
- Precise geometry
- Assembly support
- Color and material properties
Implementation:
class PLUGIN_3D_OCC : public SCENEGRAPH
{
bool Load( const wxString& filename );
void ProcessShape( const TopoDS_Shape& shape );
};
Capabilities:
- Solid modeling
- Surface geometry
- Assembly hierarchies
- Compound shapes
VRML (Virtual Reality Modeling Language)
Plugin: plugins/3d/vrml/
Versions supported:
- VRML 1.0 (
v1/)
- VRML 2.0/VRML97 (
v2/)
- X3D (partial)
Features:
- Mesh-based models
- Materials and textures
- Transformations
- Hierarchical scenes
Parser structure:
class VRML1_BASE
{
virtual bool Read( WRLPROC& proc );
virtual void TranslateToSG( SCENEGRAPH* scene );
};
class VRML1_SEPARATOR : public VRML1_BASE { };
class VRML1_MATERIAL : public VRML1_BASE { };
class VRML1_COORDINATE : public VRML1_BASE { };
Plugin: plugins/3d/idf/
Purpose:
- Board outline exchange
- Component placement
- Mechanical CAD integration
Format versions:
- IDF 2.0
- IDF 3.0 (most common)
- IDF 4.0
Plugin Architecture
Base class:
class S3D_PLUGIN
{
virtual SCENEGRAPH* Load( const wxString& filename ) = 0;
virtual wxString GetFileExtension() const = 0;
virtual wxString GetFilesFilter() const = 0;
};
Scene graph:
class SCENEGRAPH
{
std::vector<SCENEGRAPH*> children;
std::vector<SGCOLOR> colors;
std::vector<VECTOR3D> vertices;
std::vector<int> indices;
void AddNode( SCENEGRAPH* node );
void SetColor( float r, float g, float b, float a );
};
Registration: Plugins are dynamically loaded at runtime based on file extension.
I/O Plugins
Purpose
Enable import/export of various EDA file formats.
Plugin Interface
class IO_BASE
{
virtual void Save( const wxString& filename,
BOARD* board,
const STRING_UTF8_MAP* props = nullptr );
virtual BOARD* Load( const wxString& filename,
BOARD* board,
const STRING_UTF8_MAP* props = nullptr );
virtual void FootprintEnumerate( wxArrayString& list,
const wxString& libPath );
virtual FOOTPRINT* FootprintLoad( const wxString& libPath,
const wxString& name );
};
Altium
Plugin: common/io/altium/
Formats:
.PcbDoc - PCB files
.SchDoc - Schematic files
.PcbLib - Footprint libraries
.SchLib - Symbol libraries
Parsers:
altium_binary_parser.cpp - OLE compound documents
altium_ascii_parser.cpp - ASCII sections
altium_props_utils.cpp - Property extraction
EAGLE
Plugin: common/io/eagle/
Formats:
.brd - Board files (XML)
.sch - Schematic files (XML)
.lbr - Libraries (XML)
Parser: XML-based using TinyXML2
EasyEDA
Plugin: common/io/easyeda/, common/io/easyedapro/
Formats:
- JSON-based project files
- Embedded libraries
- Cloud project exports
Variants:
- EasyEDA Standard
- EasyEDA Pro
CADSTAR
Plugin: common/io/cadstar/
Formats:
- Archive-based projects
- Parts library database
Features:
- Complex hierarchical designs
- Custom attributes
- Net classes
Plugin Registration
IO_MGR handles plugin discovery:
class IO_MGR
{
static IO_BASE* PluginFind( IO_FILE_TYPE fileType );
enum IO_FILE_TYPE {
KICAD_SEXP,
LEGACY,
ALTIUM_DESIGNER,
EAGLE,
EASYEDA,
CADSTAR_PCB_ARCHIVE,
// ...
};
};
IPC API
Overview
Modern external tool integration via Protocol Buffers and NNG transport.
Introduced: KiCad 8.0
Location: api/
Architecture
Protocol Buffers
Definitions: api/proto/
Message structure:
// From common/envelope.proto
message ApiRequest {
ApiRequestHeader header = 1;
google.protobuf.Any message = 2;
}
message ApiResponse {
ApiResponseHeader header = 1;
ApiResponseStatus status = 2;
google.protobuf.Any message = 3;
}
enum ApiStatusCode {
AS_OK = 1;
AS_BAD_REQUEST = 3;
AS_NOT_READY = 4;
AS_UNHANDLED = 5;
AS_BUSY = 7;
}
Message Types
Board commands (board/board_commands.proto):
message GetOpenBoardsRequest {}
message GetOpenBoardsResponse {
repeated BoardHeader boards = 1;
}
message RunDrcRequest {
string board_id = 1;
}
Common commands (common/commands/):
base_commands.proto - Basic operations
editor_commands.proto - Editor control
project_commands.proto - Project management
Transport Layer
NNG (nanomsg-next-gen): Message queue system
Endpoint: ipc:///tmp/kicad-api.sock (Unix) or named pipe (Windows)
Patterns:
- Request/Reply - Synchronous commands
- Publish/Subscribe - Event notifications
Client Integration
Python example
import pynng
from api.board import board_pb2
from api.common import envelope_pb2
# Connect to KiCad API
sock = pynng.Req0()
sock.dial("ipc:///tmp/kicad-api.sock")
# Create request
request = envelope_pb2.ApiRequest()
request.message.Pack(board_pb2.GetOpenBoardsRequest())
# Send and receive
sock.send(request.SerializeToString())
response_data = sock.recv()
response = envelope_pb2.ApiResponse()
response.ParseFromString(response_data)
if response.status.status == envelope_pb2.AS_OK:
boards = board_pb2.GetOpenBoardsResponse()
response.message.Unpack(boards)
for board in boards.boards:
print(f"Open board: {board.name}")
Use Cases
Automation:
- CI/CD integration
- Batch processing
- Design validation
- Report generation
External tools:
- Custom DRC checks
- Advanced routing algorithms
- Library management
- Manufacturing preparation
Testing:
- Automated testing
- Regression validation
- Performance benchmarking
Security
Token validation: Prevents unauthorized access
message ApiRequestHeader {
string kicad_token = 1; // Must match running instance
string client_name = 2; // Client identification
}
Limitations:
- Local-only by default (IPC sockets)
- No authentication (relies on OS permissions)
- Trusted client assumption
Plugin Development Guidelines
Python Plugins
Best practices:
- Handle exceptions gracefully
- Validate board state before modifications
- Use transactions for multiple operations
- Refresh UI after changes
- Provide meaningful error messages
Testing:
class TestPlugin(unittest.TestCase):
def setUp(self):
self.board = pcbnew.CreateEmptyBoard()
def test_plugin_operation(self):
plugin = MyPlugin()
plugin.Run()
self.assertEqual(len(self.board.GetFootprints()), 10)
I/O Plugins
Requirements:
- Inherit from
IO_BASE
- Register with
IO_MGR
- Handle malformed input
- Preserve as much data as possible
- Document format limitations
3D Plugins
Requirements:
- Implement
S3D_PLUGIN interface
- Build scene graph efficiently
- Handle materials/colors
- Support coordinate transformations
- Validate geometry
See Also