Skip to main content
tscircuit Essentials

Biscuit Board Laser Ablation

The laser_prefab autorouter pairs tscircuit with a fabrication process that combines laser ablation and a "biscuit" carrier board. Fabricators pre-drill a matrix of vias into an inexpensive substrate—the biscuit—then laminate thin copper to the top and bottom. A UV or IR laser ablates the copper, defining the traces while leaving the via barrels intact. Because the vias are prefabricated, you route against a known template instead of drilling new holes for every board.

This guide walks through designing for that workflow. You'll learn how to:

  1. Build a reusable via template (the biscuit board).
  2. Place that template, route with autorouter="laser_prefab", and confirm the results match the prefabricated geometry.

1. Build a reusable via template (a biscuit board)

Create a component for your biscuit template that contains every via location available on the board. Mark each via with netIsAssignable so it is treated as an assignable via when the router runs. The vias can optionally include default net names to serve as documentation for repeated layouts.

src/biscuit-template.tsx
import { Fragment } from "react"

export const BiscuitTemplate = () => (
<Fragment>
<via name="B1" pcbX={-4} pcbY={6} fromLayer="top" toLayer="bottom" netIsAssignable />
<via name="B2" pcbX={0} pcbY={6} fromLayer="top" toLayer="bottom" netIsAssignable />
<via name="B3" pcbX={4} pcbY={6} fromLayer="top" toLayer="bottom" netIsAssignable />
<via name="B4" pcbX={-4} pcbY={0} fromLayer="top" toLayer="bottom" netIsAssignable />
<via name="B5" pcbX={0} pcbY={0} fromLayer="top" toLayer="bottom" netIsAssignable />
<via name="B6" pcbX={4} pcbY={0} fromLayer="top" toLayer="bottom" netIsAssignable />
</Fragment>
)

Keep the template focused on the vias themselves. Copper features such as fiducials or alignment marks should live in their own components so you can swap templates without affecting the mechanical stackup.

2. Place the biscuit template, route, and validate

Include the template inside your <board /> before adding components. Because the vias are already drilled in the physical biscuit, avoid translating or rotating the template in a way that misaligns the coordinates.

export default () => (
<board width="20mm" height="20mm" autorouter="laser_prefab">
<group name="biscuit" pcbX={0} pcbY={0}>
<via name="B1" pcbX={-4} pcbY={6} fromLayer="top" toLayer="bottom" netIsAssignable />
<via name="B2" pcbX={0} pcbY={6} fromLayer="top" toLayer="bottom" netIsAssignable />
<via name="B3" pcbX={4} pcbY={6} fromLayer="top" toLayer="bottom" netIsAssignable />
<via name="B4" pcbX={-4} pcbY={0} fromLayer="top" toLayer="bottom" netIsAssignable />
<via name="B5" pcbX={0} pcbY={0} fromLayer="top" toLayer="bottom" netIsAssignable />
<via name="B6" pcbX={4} pcbY={0} fromLayer="top" toLayer="bottom" netIsAssignable />
</group>

<testpoint name="TP_TOP" footprintVariant="pad" pcbX={0} pcbY={9} layer="top" />
<testpoint name="TP_BOTTOM" footprintVariant="pad" pcbX={0} pcbY={-9} layer="bottom" />
</board>
)
PCB Circuit Preview

Keep the board outline slightly inside the biscuit's usable area so the laser can clear debris without hitting the rails.

Once the template is in place, add traces exactly as you would for a conventional board. The router treats assignable vias as neutral territory: any net can claim them provided both layers are available and no design rules are violated.

src/laser-prefab-example.tsx
<board width="20mm" height="20mm" autorouter="laser_prefab">
<BiscuitTemplate />

<chip
name="U1"
footprint="soic8"
pcbX={-6}
pcbY={0}
connections={{ pin1: "R1.pin1", pin8: "B6.top" }}
/>
<resistor name="R1" resistance="1k" footprint="0402" pcbX={6} pcbY={0} />

<trace from="TP_TOP.pin1" to="B2.top" />
<trace from="B2.bottom" to="TP_BOTTOM.pin1" />
</board>

After generating manufacturing data (Gerber or ODB++ exports) or reviewing the PCB preview, confirm that:

  • Every claimed via matches a real location on the biscuit template.
  • Unused vias remain isolated and keep their original net names.
  • Trace clearances respect your fabrication limits.
export default () => (
<board width="20mm" height="20mm" autorouter="laser_prefab">
<group name="biscuit">
<via name="B2" pcbX={0} pcbY={6} fromLayer="top" toLayer="bottom" netIsAssignable />
<via name="B5" pcbX={0} pcbY={0} fromLayer="top" toLayer="bottom" netIsAssignable />
</group>

<testpoint name="TP_TOP" footprintVariant="pad" pcbX={0} pcbY={9} layer="top" />
<testpoint name="TP_BOTTOM" footprintVariant="pad" pcbX={0} pcbY={-9} layer="bottom" />

<trace from="TP_TOP.pin1" to="B2.top" />
<trace from="B2.bottom" to="B5.top" />
<trace from="B5.bottom" to="TP_BOTTOM.pin1" />
</board>
)
PCB Circuit Preview