Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Type System

Orrery’s type system lets you define reusable visual styles and apply them consistently across your diagrams. Types build on built-in base types and can be composed and extended.

Defining types

Use the type keyword to create a named type from a base type with attributes:

type TypeName = BaseType [attributes];

Type names must be CamelCase starting with an uppercase letter.

diagram component;

type Service = Rectangle [fill_color="#e6f3ff", rounded=5];
type Database = Rectangle [fill_color="#e0f0e0", rounded=10];

api as "API Gateway": Service;
db as "Users DB": Database;
api -> db;

Rendered diagram

Declarations vs. invocations

The type system has two ways to use types, depending on the construct:

Declarations (:)

Create a named component that can be referenced in relations. Used for defining components and participants.

identifier: TypeName;
identifier: TypeName [attribute_overrides];
diagram sequence;

type Participant = Rectangle [fill_color="#e6f3ff", stroke=[color="#336699"]];

client as "Browser": Participant;
api as "API Gateway": Participant;

client -> api: "Request";

Rendered diagram

Invocations (@)

Apply a type to a construct — relations, notes, activations, or fragments. These are anonymous actions, not named entities.

keyword @TypeName ...
keyword @TypeName [attribute_overrides] ...
diagram sequence;

type ErrorArrow = Arrow [stroke=[color="#cc3333", width=2.0]];
type WarningNote = Note [background_color="#fff3cd", stroke=[color="orange"], text=[color="#856404"]];

client: Rectangle;
server: Rectangle;

client -> @ErrorArrow server: "Bad request";
note @WarningNote [on=[server]]: "Rate limit approaching";

Rendered diagram

Default types

When @TypeSpec is omitted, Orrery uses a default:

ConstructDefault typeSugarExplicit equivalent
RelationsArrowa -> ba -> @Arrow b
NotesNotenote: "text"note @Note: "text"
ActivationsActivateactivate x { }activate @Activate x { }
FragmentsFragmentalt "cond" { }alt @Fragment "cond" { }

You can still pass inline attributes when using the sugar form:

client -> [stroke=[color="red"]] server;  // same as: client -> @Arrow[stroke=[color="red"]] server;

Built-in base types

Component shapes

TypeDescriptionCan contain children
RectangleRectangular boxYes
OvalElliptical shapeYes
ComponentUML component iconYes
ActorStick figureNo
EntityDiamond shapeNo
ControlCircleNo
InterfaceCircle with labelNo
BoundaryRounded rectangleNo

Relation type

TypeDescription
ArrowConfigurable arrow for connections between components

Construct types

TypeDescription
NoteAnnotations attached to components or placed in margins
ActivateActivation boxes on sequence diagram lifelines
FragmentInteraction fragments (alt, opt, loop, par, break, critical)

Attribute group types

TypeDescription
StrokeReusable group of stroke attributes (color, width, style, cap, join)
TextReusable group of text attributes (font_size, font_family, color, background_color, padding)

Attribute group types follow the same type definition syntax as other types and support composition and overrides. They are used inside other type definitions as attribute values, not for creating components directly. See Styling for attribute details.

diagram component;

type ThickBlue = Stroke [color="steelblue", width=2.5];
type Heading = Text [font_size=16, color="darkblue", font_family="Arial"];

// Named attribute group usage
type Service = Rectangle [fill_color="#e6f3ff", stroke=ThickBlue, text=Heading];

// Named attribute group with overrides
type Alert = Rectangle [fill_color="#ffe0e0", stroke=ThickBlue, text=Heading[color="red"]];

// Anonymous attribute group usage
type Database = Rectangle [fill_color="#e0f0e0", stroke=[color="green", width=1.5]];

api as "API Gateway": Service;
auth as "Auth Service": Service;
alert as "Alert Service": Alert;
db as "Users DB": Database;
api -> auth;
api -> alert;
auth -> db;

Rendered diagram

Type composition

Types can extend other types. Later attributes override earlier ones:

diagram sequence;

// Base types
type ThickSolid = Stroke [color="steelblue", width=2.5];
type BoldText = Text [font_size=16, color="darkblue", font_family="Arial"];

// Component type using attribute groups
type Service = Rectangle [fill_color="#e6f3ff", stroke=ThickSolid, text=BoldText];

// Extended type — overrides fill_color and stroke color
type CriticalService = Service [fill_color="#ffe0e0", stroke=[color="red", width=3.0]];

// Arrow types with composition
type RequestArrow = Arrow [stroke=ThickSolid];
type UrgentRequest = RequestArrow [stroke=[color="red"]];

client as "Browser": Service;
api as "API Gateway": CriticalService;

client -> @RequestArrow api: "Normal request";
client -> @UrgentRequest api: "Urgent request";

Rendered diagram

The inheritance chain resolves attributes step by step:

  • CriticalService inherits Service’s stroke and text, then overrides fill_color and stroke
  • UrgentRequest inherits RequestArrow’s stroke (which uses ThickSolid), then overrides the color to red

Named vs. anonymous TypeSpecs

Named TypeSpec

References a previously defined type by name:

diagram sequence;

type ResponseArrow = Arrow [stroke=[color="slategray", width=1.0, style="dashed"]];

client: Rectangle;
server: Rectangle;

server -> @ResponseArrow client: "Response";

Rendered diagram

Anonymous TypeSpec

Creates a one-off type inline with attributes, without giving it a name:

diagram sequence;

type RequestArrow = Arrow[stroke=[color="steelblue", width=1.5]];

client: Rectangle;
server: Rectangle;
db: Rectangle;

// Anonymous type extending a base type
client -> @Arrow[stroke=[color="purple", width=2.0]] server: "Request";

// Anonymous type extending a named type, overriding stroke color
server -> @RequestArrow[stroke=[color="red"]] db: "Urgent query";

Rendered diagram

Anonymous types are useful for one-off styling. If you use the same attributes more than once, define a named type instead.

Complete example

diagram sequence;

// Attribute group types
type ThinDashed = Stroke [color="slategray", width=1.0, style="dashed"];
type ThickSolid = Stroke [color="steelblue", width=2.5];
type BoldText = Text [font_size=16, color="darkblue", font_family="Arial"];

// Component types
type Service = Rectangle [fill_color="#e6f3ff", stroke=ThickSolid, text=BoldText];
type Store = Rectangle [fill_color="#e0f0e0", stroke=[color="#339966"], rounded=8];
type CriticalService = Service [fill_color="#ffe0e0", stroke=[color="red", width=3.0]];

// Arrow types
type RequestArrow = Arrow [stroke=ThickSolid];
type ResponseArrow = Arrow [stroke=ThinDashed];
type ErrorArrow = Arrow [stroke=[color="#cc3333", width=2.0, style="dashed"]];

// Construct types
type WarningNote = Note [background_color="#fff3cd", stroke=[color="orange", width=2.0], text=[color="#856404"]];
type CriticalActivation = Activate [fill_color="rgba(255,180,180,0.3)", stroke=[color="red", width=2.0]];

// Participants (declarations with :)
client as "Browser": Service;
api as "API Gateway": CriticalService;
auth as "Auth Service": Service;
primary_db as "Primary DB": Store;

// Messages (invocations with @)
client -> api: "GET /dashboard";
api -> @RequestArrow auth: "Validate session";
auth -> @ResponseArrow api: "Session valid";
note @WarningNote [on=[auth]]: "Token expires in 60s";

// Typed activation
api -> @RequestArrow primary_db: "UPDATE session.last_active";
activate @CriticalActivation primary_db {
    primary_db -> @ResponseArrow api: "Ack";
};

api -> @ResponseArrow client: "Dashboard payload";

Rendered diagram