Board Layout

Everything that defines the physical board: outlines, zones, vias, graphics, design rules, net classes, and the stackup. Placement of components is covered in Placement.

method

outline

The board outline, emitted on Edge.Cuts as native KiCAD primitives: a rectangle with optional fillets, polygons, circles, internal cutouts, and a path builder for arcs.

Example first

outline.ts
import { PCB } from '@typecad/pcb';

let pcb = new PCB('typecad_docs');
pcb.outline(100, 100, 50, 50, 1);   // x, y, w, h, fillet
ParameterTypeUnitsDescription
x, ynumbermmPosition of the top-left corner
width, heightnumbermmBoard dimensions
filletnumbermmOptional corner fillet radius

Non-rectangular boards

shapes.ts
pcb.outlinePolygon([
  { x: 0, y: 0 },
  { x: 40, y: 0 },
  { x: 40, y: 25 },
  { x: 0, y: 20 },
]);

pcb.outlineCircle(20, 12, 10);

pcb.cutoutCircle(20, 12, 3);          // internal cutout
pcb.cutout([{ x: 5, y: 5 }, { x: 9, y: 5 }, { x: 9, y: 8 }, { x: 5, y: 8 }]);

pcb
  .outlinePath(0, 0)
  .lineTo(40, 0)
  .arcTo(40, 20, { x: 46, y: 10 })    // KiCAD 3-point arc (end + mid)
  .lineTo(0, 20)
  .close();

outlinePath outlinePath(x, y): OutlinePathBuilder

Starts at (x, y), then lineTo(x, y), arcTo(endX, endY, mid) (KiCAD's 3-point arc — the arc passes through mid), and close() to seal the shape with a final line.

method

zone / keepout

Filled copper zones (ground pours) and keepout areas. Zone fills can be tuned per zone or set to KiCAD's defaults.

Example first

zones.ts
import { PCB } from '@typecad/pcb';

let pcb = new PCB('zone_example');

pcb.zone({
  net: 'GND',
  layers: ['B.Cu'],
  x: 0,
  y: 0,
  width: 50,
  height: 30,
});

pcb.keepout({
  layers: ['F.Cu', 'B.Cu'],
  x: 20,
  y: 10,
  width: 20,
  height: 15,
  restrictions: { tracks: true, vias: true, copperpour: true },
});

pcb.create();

Zone options

OptionTypeDescription
net | pinstring | PinAttaches the pour to a net; omitting both creates an unconnected pour (KiCAD net 0)
layersstring[]required — copper layers the zone fills
x, y, width, heightnumberRectangle form (mm)
pointsarrayExplicit polygon (≥ 3 vertices)
boundsBoardBoundsBounds rectangle — e.g. bounds: pcb.board; provide one geometry form, not combinations
fillobject | falseFill options (below); false leaves an unfilled outline
prioritynumberFill priority when zones overlap
namestringZone name in KiCAD

Fill options (fill: {...})

OptionTypeDescription
mode'solid' | 'hatched'Fill style
connectPads'thru_hole_only' | 'full' | 'no'Pad connections to the pour
thermalGapnumberGap around thermal relief pads (mm, default 0.254)
thermalBridgeWidthnumberSpoke width (mm, default 0.4064)
minThicknessnumberMinimum copper island thickness (mm)
smoothing'chamfer' | 'fillet' | 'none'Island corner style
islandRemovalModenumber0 never / 1 always / 2 remove islands below the minimum area (default)
islandAreaMinnumberMinimum island area (mm²) for mode 2
hatchStyle / hatchPitch / hatchThickness / hatchGapmixedHatched-fill geometry
arcSegmentsnumberFill arc approximation (default 16)

Keepout options

OptionTypeDescription
layersstring[]required — layers the keepout applies to
x, y, width, height | points | boundsmixedOne geometry form
restrictionsobject{ tracks, vias, pads, copperpour, footprints } — what is restricted in the area
placementbooleanAlso restrict footprint placement (default false)
prioritynumberKeepout priority
method

via

Vias can be created, placed, and connected like any other component — connected through pin(1). Router-placed vias follow the board's via policy, below.

Example first

via.ts
import { PCB, Resistor } from '@typecad/pcb';

let typecad = new PCB('typecad_docs');
let r1 = new Resistor({ value: '1kohm', size: '0603' });

let via = typecad.via({
  at: { x: 10, y: 10 },
  size: 0.6,
  drill: 0.3,
});

typecad.net(r1.pin(1), via.pin(1));
typecad.create(r1, via);

via (options) pcb.via({ at, size, drill, powerInfo? }): Via

ParameterTypeUnits / valuesDescription
atobjectmm{ x, y } position
sizenumbermmVia diameter (default 0.8)
drillnumbermmDrill diameter (default 0.4)
powerInfoobject—{ current, maxTempRise, thickness } — checks current against the via rating using IPC-2221 (maxTempRise default 10 °C, thickness default 35 µm)
method group

graphics

Graphics primitives drawn on the board.

Example first

MethodDescription
rect({ bounds | x,y,w,h | start,end })Rectangle
circle({ center, radius | end })Circle
line({ start, end })Line segment
poly({ points })Polygon
arc({ start, mid, end })KiCAD 3-point arc
text({ text, x, y, ... })Text on the board

Text positioning (ITextPositioning)

Board text and the per-component referenceLayout / valueLayout / fabLayout properties all take the same positioning object:

FieldTypeDescription
x, y, rotationnumberPosition (mm) and rotation (degrees)
layerstringCopper or technical layer
fontstringTrueType face — omit for KiCAD’s default stroke font
width, height / fontSizenumberGlyph size (mm)
thicknessnumberStroke thickness
bold / italic / showbooleanText style toggles
justifyobject{ horizontal: 'left'|'right'|'center', vertical: 'top'|'bottom'|'middle', mirror }
method

group

KiCAD groups — move and lay out related parts together in the editor.

Example first

group.ts
typecad.group('power', r1, c1, c2);

Accepts components and manual TrackBuilder tracks. Packages call this automatically — every package's parts land in one named group.

Design rules

Rules default to the JLCPCB no-surcharge standard and are written to ./build/{name}.kicad_pro for DRC. Override any subset with the rules constructor option; the router, via defaults, and stitching all read the final values.

rules.ts
let pcb = new PCB('typecad_docs', {
  rules: {
    min_track_width: 0.127,
    min_via_diameter: 0.5,
  },
});
Default (JLCPCB standard)Value
min_clearance0.2 mm
min_track_width0.2 mm
min_via_diameter0.6 mm
min_through_hole_diameter0.3 mm
min_via_annular_width0.15 mm
min_copper_edge_clearance0.2 mm
min_hole_to_hole0.25 mm

Net classes

method

netClass / assign

Group nets with shared width, clearance, and via dimensions. The router uses the net's class ahead of the board defaults; every class dimension is floored at the board rule.

Example first

net-classes.ts
const usb = typecad.named('USB_DP').net(u1.DP, conn.DP);

typecad.netClass('usb90', {
  track_width: 0.25,
  clearance: 0.15,
  layers: ['In1.Cu'],      // preferred routing layers
});

typecad.netClass('power', { track_width: 0.5, via_diameter: 0.8 });
typecad.assign(usb, 'usb90');
OptionTypeDescription
track_widthnumbermm — defaults to the board rule, floored at it
clearancenumbermm — same floor behavior
via_diameter / via_drillnumbermm — via dimensions for the class
layersstring[]Preferred routing layers; the router prefers them. Not written to the KiCAD project file

Stackup, planes & impedance

method

stackup

Declares the layer stack. Layers is a constructor option (2–32 copper layers); stackup() refines it with finish, dielectric constraints, and per-layer overrides. JLCPCB-standard defaults ship built in.

Example first

stackup.ts
let pcb = new PCB('four_layer', { layers: 4 });

pcb.stackup(4, {
  copper_finish: 'ENIG',
  dielectric_constraints: true,     // needed for controlled impedance
  layers: {
    'In1.Cu': { thickness: 0.035, material: 'FR4' },
    'dielectric 1': { epsilon_r: 4.5, thickness: 0.21 },
  },
});
OptionTypeDescription
copper_finish'None' | 'HASL' | 'ENIG'Surface finish (default None)
dielectric_constraintsbooleanBuild the dielectric table — required for impedance targets (default false)
layersRecord<string, override>Per-layer overrides keyed by copper name (In1.Cu), dielectric N, F.Mask, B.Mask, F.SilkS, B.SilkS, F.Paste, B.Paste
override.thicknessnumbermm — total thickness is re-compensated so the board still matches options.thickness
override.material / epsilon_r / loss_tangent / colormixedLayer material facts. Defaults follow the JLCPCB standard stackup: FR4, εr 4.5, loss tangent 0.02
methods

plane / viaPolicy

plane(net, layer) declares a board-covering power or ground pour on one copper layer — materialized at create() as a filled zone with thermal reliefs, and excluded from the router's default layers. viaPolicy controls what vias the router may place.

Example first

planes.ts
pcb.plane('GND', 'In1.Cu');     // board-covering pour with thermal reliefs
pcb.plane('VBUS', 'In2.Cu');

pcb.viaPolicy({ type: 'blind-buried', maxSpan: 2 });

viaPolicy viaPolicy({ type: 'through' } | { type: 'blind-buried', maxSpan? })

'through' is the default. With 'blind-buried', maxSpan (default 2) caps how many layer boundaries one via may cross — deeper transitions fall back to through vias.

method

impedanceWidth

Controlled impedance against the declared stackup. Outer layers model as microstrip, inner layers as symmetric stripline. With a tolerance, the width snaps to a 0.01 mm grid that stays inside the target.

Example first

impedance.ts
// standalone: the width that hits 50 Ω ± 5 on In1.Cu
let w = pcb.impedanceWidth('In1.Cu', 50, 5);

// or as a routing option — the trace widens to the target
typecad.route(usb90, { impedance: { target: 90, tolerance: 5 } });

impedanceWidth impedanceWidth(layer, targetOhms, toleranceOhms?): number

ParameterTypeUnits / valuesDescription
layerstring—A declared copper layer
targetOhmsnumber—Target characteristic impedance
toleranceOhmsnumber—Snap the width within ± this many ohms

Throws a RangeError for unknown layers or targets the stackup can't reach.

Stitching & teardrops

method

stitch

Grids of stitching vias joining a net across layers — placed at create() against the finished board, skipping anything the clearance forbids.

Example first

stitch.ts
pcb.stitch('GND', {
  layers: ['F.Cu', 'B.Cu'],   // via span (default: first → last copper layer)
  pitch: 1.5,                 // grid spacing, mm (default 1.5)
  margin: 0.5,                // inset from the board edge, mm
});
OptionTypeDescription
netstringrequired — the net the stitching vias join
layersstring[]Via span (default: through, first → last copper layer)
pitchnumberGrid spacing in mm (default 1.5)
size / drillnumberVia dimensions — default to the board rules
areaIBoundsLikeWhere to stitch (default: the board outline)
marginnumberInset from the board edge in mm (default 0.5)
method

teardrops

Teardrop reinforcement where traces meet vias and pads — written into the KiCAD project and generated as real geometry for router-placed vias.

Example first

teardrops.ts
pcb.teardrops({
  shape: 'round',       // 'round' | 'rect'
  maxLength: 1.0,       // mm
  smdPads: true,        // also on SMD pads
  trackEnds: false,     // bare track ends too
});
OptionTypeDescription
enabledbooleanMaster switch (default true)
viasbooleanTeardrop router-placed and declared vias (default true)
throughHolePads / smdPadsbooleanPad teardrops (default true)
trackEndsbooleanTeardrop bare track ends (default false)
shape'round' | 'rect'Teardrop shape (default round)
maxLength / maxHeightnumberTeardrop size limits in mm (defaults 1.0 / 2.0)
© 2026 typeCAD — code-defined electronics github