Routing a trace with pcbnew's Python API

Published on September 11, 2026 by leZ

Create a copper trace between two points, with a defined width, by script — with pcbnew or KiCad's IPC API.

Routing a bundle of identical traces by hand (a data bus, a series of connections to a connector) is repetitive and prone to width mistakes. Scripting trace creation guarantees a reproducible width and path — the starting point for any homemade auto-router.

Creating the track

Instantiate a PCB_TRACK object attached to the board, then add it:

from pcbnew import PCB_TRACK

track = PCB_TRACK(board)
board.Add(track)

With the IPC API, the board exposes a creation method directly:

from kicad import KiCad

kicad = KiCad()
board = kicad.get_board()
track = board.create_track()

Setting the path, width, and layer

The track’s start and end are set in internal units, width and layer separately:

from pcbnew import VECTOR2I, FromMM, F_Cu

track.SetStart(VECTOR2I(FromMM(10), FromMM(20)))
track.SetEnd(VECTOR2I(FromMM(40), FromMM(20)))
track.SetWidth(FromMM(0.25))
track.SetLayer(F_Cu)

The IPC API works directly in millimeters, with no conversion:

from kicad.geometry import Vector2

track.start = Vector2.from_mm(10, 20)
track.end = Vector2.from_mm(40, 20)
track.width = 0.25
track.layer = "F.Cu"
board.update_items(track)

Try it below: adjust length and width to see the trace change on the board.

track.SetStart(VECTOR2I(FromMM(10), FromMM(20)))
track.SetEnd(VECTOR2I(FromMM(40), FromMM(20)))
track.SetWidth(FromMM(0.25))
40
0.25

Connecting the track to a net

Just like a via, the track needs to be attached to an existing net:

track.SetNet(board.FindNet("GND"))

Same idea on the IPC API side, with an explicit sync back to KiCad:

track.net = board.get_net("GND")
board.update_items(track)

Going further

This skeleton generalizes to a loop that automatically connects a series of pads together — the basis for a small homemade router for repetitive topologies (buses, connector rows), instead of drawing every trace by hand.