makeIRLEngineering notes

KiCad

KiCad Custom Design Rules (.kicad_dru): Syntax and Examples

Write KiCad custom design rules for fab limits, high-voltage clearance, and edge spacing. Syntax, conditions, rule order, and tested patterns to copy.

Published Updated

What custom rules are for

Board Setup gives you global minimums: track width, clearance, drill, annular ring. Custom rules handle everything those fields cannot say, such as “this net class needs 0.5 mm of clearance”, “no copper within 0.3 mm of the board edge”, or “vias under this part must be larger”. They live in a text file next to the project, named after it with the .kicad_dru extension, and the DRC reads it along with the board setup.

Open it from Board Setup, Design Rules, Custom Rules. The editor has a syntax checker, so you can paste a rule and see errors immediately.

Anatomy of a rule

(version 1)

(rule "HV clearance"
  (constraint clearance (min 0.5mm))
  (condition "A.NetClass == 'HV'"))

A rule has a name, one or more constraints, and an optional condition. If there is no condition, the rule applies to every object. The condition is evaluated against a pair of objects, A and B, which is why clearance conditions often look at both sides.

Common constraint types include clearance, track_width, via_diameter, hole_size, annular_width, edge_clearance, courtyard_clearance, hole_clearance, hole_to_hole, and silk_clearance. Most accept min, max, or opt.

Useful condition terms: A.NetClass, A.Type (for example 'Via' or 'Track'), A.Layer, A.insideArea('name') for a rule area, and A.Name for a net name. Combine them with && and ||.

Rule order matters

When several rules match the same pair of objects, later rules in the file take precedence over earlier ones. Put your general rule first and the exceptions afterwards. If a clearance you set seems to be ignored, a later, broader rule is probably overriding it.

Examples

Encode the fab’s drill and annular limits so DRC fails before the fab does:

(rule "fab min drill"
  (constraint hole_size (min 0.3mm)))

(rule "fab annular ring"
  (constraint annular_width (min 0.13mm)))

Use the numbers from your chosen service; do not copy these. Fab limits differ by service and layer count.

More clearance for a mains or high-voltage net class:

(rule "HV to everything"
  (constraint clearance (min 1.0mm))
  (condition "A.NetClass == 'HV'"))

The required distance for real mains work comes from the safety standard that applies to your product, not from a blog example. Treat the number here as a placeholder.

Keep copper off the board edge:

(rule "copper to edge"
  (constraint edge_clearance (min 0.3mm)))

A different limit for one region only, using a rule area named dense that you drew around a fine-pitch part:

(rule "fine tracks near U1"
  (constraint track_width (min 0.127mm))
  (condition "A.insideArea('dense')"))

(Regions where copper must not exist at all, such as under an antenna, are usually simpler as a rule area with keepout enabled; see KiCad rule areas.)

Testing a rule

  1. Save the file and run DRC. A good rule should produce a new violation on a board you know breaks it.
  2. Make a deliberate violation (move a track toward the net) and confirm the marker appears with your rule’s name.
  3. Remove the deliberate violation and confirm the marker clears.

A rule you never saw fire is a rule you cannot trust. Syntax can be valid while the condition matches nothing, for example when a net class name is misspelled.

Run it in automation

Custom rules are read by kicad-cli, so the same file runs in a headless check. See headless KiCad with kicad-cli for a command that fails a script on violations. Keep the .kicad_dru file in version control with the board so the check is repeatable.