---
title: "Assembly and outputs"
description: "The part held still, how the piece is grouped and taken apart, and what gets drawn, exported and tabulated."
url: https://kaicad.barpom.xyz/docs/schema/assembly-and-outputs
schema: "0.1"
source: packages/spec/src/design.ts
---

# Assembly and outputs

## `assembly`

```yaml
assembly:
  ground:
    part: headboard_panel
    at: [0, 0, (headboard_height - 40) / 2]
    orient: { length: x, width: -z, thickness: y }
  groups:
    - { id: head_end, label: Head end, members: [head_post@left, head_post@right, headboard_panel] }
    - { id: base,     label: Base,     members: [side_rail@*, slat_cleat@*] }
  disassembly:
    - { id: slats, label: Lift out the slats, removes: [slat@*] }
    - { id: rails, label: Unbolt the rails,   removes: [side_rail@*] }
    - { id: ends,  label: Separate the ends,  removes: [foot_end, head_end] }
```

### `ground`

The part held still. Everything else is positioned relative to it through the chain of joints.

```yaml
ground: cleat              # shorthand, when the defaults are right
```

```yaml
ground:
  part: headboard_panel
  orient: { length: x, width: -z, thickness: y }
  at: [0, 0, (headboard_height - 40) / 2]
```

**`orient`** maps the ground part's own axes onto world axes. Without it, a part's `length`
runs along world X, its `width` along Y and its `thickness` along Z — which lies a headboard
panel flat on the floor. The declaration above stands it up: its length spans the bed's width
along X, its width runs *up* (`-z` because the panel's `start` is its top edge in this
design), and its 18 mm thickness runs front-to-back along Y.

**`at`** places the ground part's origin in world space. This is the one place in the whole
format where a coordinate is legitimate, and it is doing one job: putting the piece at a
sensible height so that `z` means *height above the floor* and the ergonomic checks have a
datum. Get that wrong and every height-based finding is measured from the wrong place.

**Choose the ground part for symmetry.** Grounding the headboard panel rather than a post
makes the queen bed symmetric about its centre line for free: the two posts hang off the
panel's ends, the rails off the posts, the foot posts off the rails. Grounding a post instead
would make every dimension relative to one corner, and half the offsets would become
coordinates in disguise.

### `groups`

Named collections, used by the exploded view, the isolate control in the workbench and the
disassembly steps.

```yaml
groups:
  - id: base
    label: Base
    members: [side_rail@*, slat_cleat@*]
```

`@*` matches every instance of a part.

### `disassembly`

How the piece comes apart, in order. It is **reversed** to produce the assembly steps, because
taking something apart is the direction people can actually describe.

```yaml
disassembly:
  - { id: slats, label: Lift out the slats, removes: [slat@*] }
  - { id: rails, label: Unbolt the rails,   removes: [side_rail@*] }
  - { id: ends,  label: Separate the ends,  removes: [foot_end, head_end] }
```

`removes` takes part references and group ids. This is also what `requirements.knock_down` is
checked against: every joint crossed by a disassembly step has to be one that actually undoes.

## `outputs`

```yaml
outputs:
  drawings:
    assembly: { views: [iso, front, side, plan], sheet: a3, scale: auto }
    parts: { all: true, sheet: a4, dimension: envelope_and_features }
    details: [rail_to_head_post_left, cleat_to_rail_left]
    exploded: true
  exports: [step, glb, svg]
  data: [cutlist, bom, assembly_steps, validation]
```

Optional in full. Omit the section and you get the defaults — a compile, a cut list, a BOM and
a validation report.

### `drawings`

| Key | |
| --- | --- |
| `assembly.views` | `iso`, `front`, `side`, `plan`, `back`, `bottom` |
| `assembly.sheet` | `a4`, `a3`, `a2`, `a1` |
| `assembly.scale` | `auto`, or a number |
| `parts.all` | One sheet per part |
| `parts.only` | A list of part ids instead |
| `parts.dimension` | `envelope`, `features`, `envelope_and_features` |
| `details` | Joint ids to draw as detail views |
| `exploded` | Add an exploded assembly view |

> The `drawing` lane is not built yet. These keys are part of the schema and are accepted;
> the sheets themselves arrive with that lane. Everything else on this page compiles today.

### `exports`

`step` · `glb` · `stl` · `3mf` · `svg` · `dxf` · `pdf`

STEP is the one to hand to another CAD package; GLB is the one the viewer uses; STL is for
printing a test fit of a joint before cutting timber.

### `data`

`cutlist` · `bom` · `assembly_steps` · `validation`

| | |
| --- | --- |
| `cutlist` | Every part, grouped by stock, with rough sizes including the material's allowance |
| `bom` | Every fixture, with pack sizes and counts |
| `assembly_steps` | `disassembly`, reversed |
| `validation` | The report — [reading one](/docs/validation/reading-a-report) |

## From the command line

```
fcad compile design.yaml -o out/     everything
fcad check design.yaml               validation only, no kernel
fcad cutlist design.yaml             the cut list
fcad inspect design.yaml             where every part ended up
fcad check design.yaml --md          the report, ready to paste back
```

`--no-geometry` skips the CAD kernel. The rules that need solids are then reported as
**unverified** rather than passed, and the report says which and why — a clean bill of health
you did not earn is the most misleading thing this tool could give you.
