# Type Alias: Shape

[**lifecycle-kit**](https://jonbogaty.com/lifecycle-kit/api/readme/index.md)

***

[lifecycle-kit](https://jonbogaty.com/lifecycle-kit/api/readme/index.md) / [forms](https://jonbogaty.com/lifecycle-kit/api/forms/readme/index.md) / Shape


# Type Alias: Shape {#type-alias-shape}


> **Shape** = ([`SubPath`](https://jonbogaty.com/lifecycle-kit/api/forms/interfaces/subpath/index.md) \| [`Ellipse`](https://jonbogaty.com/lifecycle-kit/api/forms/interfaces/ellipse/index.md)) & `object`

Defined in: [forms/path.ts:200](https://github.com/jbcom/lifecycle-kit/blob/074e4e7b8038d3e2de9eb44c4b5b5aee0ef02b48/src/forms/path.ts#L200)

One drawable outline.

Not styled. A shape says where it is and which part it belongs to, never
what colour it is — pigment and lighting come from their respective stages,
both of which derive colour from biology rather than
from a form rule picking one. Baking a fill into a rule's output would make
`taper` an art director.

The tag is OPTIONAL, and that is what keeps the flatness honest. A rule that
has nothing meaningful to say about anatomy omits it and the shape compares
exactly as before; a consumer that does not care about parts ignores it
entirely. It adds a channel without adding a required ceremony.

Crucially it is plain data — a string and a number, no transform, no parent
pointer, no nesting. Grouping and transforms are separable concerns, and
conflating them is what made an earlier draft reject grouping outright: a
scene-graph node would have needed a matrix to be worth having, and a matrix
would have broken exact comparability. A label breaks nothing. Two shapes
with equal geometry and equal tags are still `toEqual`, and a tagged path
still JSON round-trips.


## Type Declaration {#type-declaration}



### tag? {#tag}


> `readonly` `optional` **tag?**: [`PartTag`](https://jonbogaty.com/lifecycle-kit/api/forms/interfaces/parttag/index.md)
