The Aster agentic UI library, rebuilt as working code.

Twenty-four components reconstructed from the source design system, down to its variables, variants and layer stacks, then wired up so they actually respond. Same tokens, same geometry, real behaviour.

Browse primitives
24components
38design tokens
0dependencies
Jade idle 00:00

An agent run, end to end

Message, reasoning, tool calls, citations, a code block and an approval. Every component on this page, composed into one flow.

Prompt

Agent4 states

A multi-state input for agent conversations

The composer carries the whole turn: idle, submitted, running, interruptible. Send a prompt and the status header appears, tasks tick through, and the send button becomes a stop button until the run ends or you halt it.

Status/Default

Message

Agentuser · agent

The two sides of a turn

A user turn is contained in an elevated bubble; an agent turn runs full width on the base surface, because it's the longer read. Row actions stay hidden until hover or keyboard focus, so a long thread isn't a wall of buttons.

Type/User · Agent
OR
You
Which of our OAuth clients still hold offline access and haven't been used in 90 days?
Jade

Three clients match. legacy-reporting is the one I'd act on today, because its owner was deprovisioned in March, so nobody is accountable for the refresh token it still holds.

Copy Retry

Reasoning

Agentdisclosure

Thinking, collapsed by default

While the agent is working the header counts up live; once it settles it becomes a static "Thought for 4s" you can open. Collapsed is the default because reasoning is reference material, not the answer.

State/Settled

Tool Call

Agentqueued · running · ok · failed

What the agent actually did

Collapsed to a single line so the transcript stays readable, with arguments and raw result underneath. Failed calls open themselves, so the one you need to read is already open.

Status/3 calls

Task List

Agentplan

The plan, visible before it runs

Every step is listed up front and dimmed until reached, so the shape of the work is legible from the start. The count in the status label is derived from the list rather than written twice.

Progress/0/5

Ready to start

Approval

Agenthuman-in-the-loop

The agent asks before it writes

A privileged change is shown as a diff with its blast radius spelled out, and the confirm stays disabled until the consequence is acknowledged. Approval is reversible for a few seconds afterwards.

State/Pending

Citation

Agentinline · hover card

Claims that carry their source

A numbered marker sits inline without breaking the line rhythm. Hover or focus it to see which record the sentence came from. The check happens where the claim is, not in a footnote nobody scrolls to.

Behaviour/hover or Tab to a marker

Three clients still hold offline_access past 90 days of inactivity. The owner of legacy-reporting was deprovisioned on 14 March, which leaves its refresh token unowned.

Agent Card

Agent6 identities

Pick an agent by its face

Each agent owns one of the six gradient identities, so it's recognisable before you read the name. Selecting a card swaps the identity used across the demos on this page, including the run in the header.

Selected/Jade

Command Menu

Shell⌘K

Every component, one keystroke away

Subsequence matching, grouped results and full keyboard control. Typing agcd still finds Agent Card. Bound globally, so press ⌘K anywhere on this page.

K

Code Block

Contentcopy

Code the agent wrote

Language on the left, copy on the right, and a confirmation that replaces the button's own label rather than firing a toast, because the feedback belongs where the click happened.

Language/TypeScript
typescript
// revoke clients with no accountable owner
export async function sweep(clients: Client[]) {
  const stale = clients.filter(
    (c) => c.idleDays > 90 && c.owner === null
  );
  for (const c of stale) await revoke(c.id);
  return stale.length;
}

File Card

Contentupload · ready

An attachment with a state

The same card covers uploading, ready and failed. Progress is a track rather than a spinner because the wait is bounded and the user can see it end.

State/Ready

Image Grid

Content1 to 4 up

Attachments in a message

The layout changes shape with the count: one fills, two split, three give the first image the tall slot, four go quarters. Past four the last cell carries the overflow count.

Count/3

Empty State

Content4 reasons

Nothing here, and why

Four different empties that need four different answers. "No results" offers a way back; "no access" names the missing scope; an error separates a retry from a status page. Only the first is really empty.

Button

Primitives3 types · 4 states

Type × Status × Disabled × Danger

Hover and press are translucent overlays, not separate fills. One ::after layer takes interaction/hover or interaction/press, inverted on dark fills. That's why this matrix is a single component, not twelve.

Status/Default · Hover · Press · Disabled
Live/hover and press these
With affordances/counter · async

Icon Button

Primitives2 shapes

Type × Shape × isFloating

32px square in both shapes: capsule and 8px rectangle. The floating variant is the only one carrying Shadow/Default; it's meant to sit over content, not inside a row.

Shape/Rounded

Shortcuts

Primitiveschord display

Key combinations, rendered readably

A 20px cap on radius/control-tiny. Combine tightens the gap so a chord reads as one unit. The capture below listens for real keystrokes, so click it and press any combination.

Combine/False · True
K P esc
Live capture/click the field, then press keys

Chip

Primitivessuggestion

Suggested actions above the composer

Secondary text, 8px radius, hairline border. Selecting one fills the composer and dismisses the set. Chips are a shortcut into the input, not a filter, so they don't persist once used.

Behaviour/select to fill the Prompt

Tag

Primitives8 tones

Palette-tinted status labels

Each tone is a bg/text pair straight out of Color/Palette, so contrast is settled in the token layer rather than per use. Click the last one to cycle it.

Tone/8
neutralverifiedrunning queuedreviewflagged archivedfailed
Live/click to cycle

Avatar

Primitives17 variants

Type × Color × Agent

The Agent type isn't a gradient fill. Each identity is a stack of rotated, blurred rounded rectangles lit by inset glows, exactly as the source symbols build them. Reproduced layer for layer, then scaled by a single custom property.

Type/Empty · Logo · Alpha Bet
OROROR OROROR OROR
drives every Alpha Bet avatar above
Type/Agent: Bloom · Silk · Flare · Nova · Void · Jade
Size/64 · 48 · 32 · 24
Avatar Group/overlap + overflow
+4
+9

Loading

Primitives2 types

Step indicator and status label

Three 2.667px dots stepping in sequence, the same indicator the Prompt uses in its status panel. Paired with a count it becomes the Status Label. Both hold still under prefers-reduced-motion.

Type/Step · Circle

Tooltip

Primitivesinverse

Naming an icon-only control

Inverse fill so it reads over any surface. It opens on focus as well as hover, which is the whole point, because an icon button with no visible label is unusable by keyboard otherwise.

Trigger/hover or Tab
Attach a file Mention a source Retry this turn

Tokens

Foundationsdesign tokens

Read from the file, not eyeballed

Every value on this page comes from the library's own tokens: the palette pairs, the interaction overlays, the 4/6/8/12/16 spacing steps and the four radii. Nothing is a hardcoded hex at the point of use.

Color/Palette
Color/Bg · Text · Border · Status
Radius/4 · 8 · 16 · 999