Reference
Components
Every component here is live and built from the role tokens. Change the theme or density in the header and they all update in place. Press Ctrl K for the command palette.
01 / Buttons
One primary action per view
Other buttons are outline or ghost. Buttons in a group share their borders, so two 1px lines never end up next to each other.
- Variants
- Sizes
- Group
-
- Segmented
- Checked segment inverts · see 15
02 / Fields
Labels go above, and helper text stays visible
There are no floating labels. Their animation and their spot on the border both clash with the rest of the system. Focus draws an inset ring, so the layout doesn't move.
Boxed (default)
Lowercase, hyphens only.
This key has been revoked.
Underlined (industrial)
Textarea & search
03 / Selection
The radio is a square too
This breaks with convention on purpose, and people push back on it more than anything else. Keep it anyway. One round control in a square interface looks like a mistake.
- Checkbox
- Radio
- Toggle
04 / Tags & status
Tags and status marks are square
No pills and no round dots. A status always has both a shape and a word.
- Tags
- neutral accent passing degraded failing 128 small
- Status
- Operational Degraded Outage Not deployed
- Keys
- ⌘K esc ⇧↵
05 / Cards
Cards share one grid and one set of lines
The grid has a 1px gap over a background in the border colour, and that gap is the border you see. The cards have no borders of their own, so lines never double up or drift out of line.
01
Immutable deploys
Every build is content-addressed and kept for 90 days. Roll back in under a second.
02
Edge routing
Requests terminate at the nearest of 310 locations, with automatic failover.
03
Zero-config TLS
Certificates issued, renewed and stapled without a line of configuration.
Deployment
edge-router
Pushed 12 minutes ago by a teammate from main at
8f3a1c.
Stat tiles
Requests
2.41M
▲ 12.4% vs last week
Error rate
0.04%
▲ 0.01pp vs last week
06 / Tabs & table
Boxy is at its best with dense data
Headers are uppercase mono on a darker strip. Rows are split by 1px lines, with no vertical lines. Numbers are right-aligned with tabular figures. Use the arrow keys to move between tabs.
| Service | Region | Status | p95 | Requests | Error rate | |
|---|---|---|---|---|---|---|
| edge-router | us-east-1 | Healthy | 41 ms | 2,410,882 | 0.04% | |
| api-gateway | eu-west-2 | Healthy | 88 ms | 1,092,441 | 0.11% | |
| image-proxy | ap-south-1 | Degraded | 612 ms | 318,204 | 2.80% | |
| webhook-fanout | us-east-1 | Failing | — | 0 | 100.00% | |
| cron-worker | eu-west-2 | Paused | — | 0 | — |
No staging services
Services promoted from development appear here before they reach production.
| Service | Branch | Updated |
|---|---|---|
Skeletons pulse in four hard steps with steps(4, end). No sweeping shimmer
07 / Feedback
Callouts, overlays and progress
Scheduled maintenance
Read replicas will fail over on Sunday at 02:00 UTC.
Certificate issued
Auto-renews 30 days before expiry.
Approaching quota
You have used 84% of this month's build minutes.
Deployment failed
Build step 4 exited with code 1.
- Overlays
- Hover for a tooltip
- Progress
-
68% · 34 of 50 steps
Indeterminate
- Skeleton
-
09 / Popover & drawer
Popovers can hold controls. Tooltips can't.
A popover holds controls and stays open until you dismiss it. A drawer is a modal panel that opens from the end side and follows the same focus rules as a dialog.
- Popover
-
Esc and outside-click dismiss · focus returns to the trigger
Metric
p95 latency
95% of requests completed faster than this. Measured at the edge, excluding cold starts.
- Drawer
- 400px · slides 100% in 160ms sharp · scrim, focus trap, Esc
11 / Accordion
Accordions built on native disclosure
It's built on <details>, so it works
without JavaScript and the browser's find-in-page can open a matching item. Give
the items the same name and only one can be open at
a time.
Exclusive: one open at a time
01What counts as a build minute?
Wall-clock time from the first build step to the upload finishing, rounded up to the next minute per build.
02Can I bring my own domain?
Yes, on every plan. Point a CNAME at edge.orbit.app; certificates are issued automatically.
03What happens when I hit a limit?
Nothing stops. You get an email at 80% and 100%, and overage is billed at the published rate.
Independent: for settings groups
Build & output
- Command
- orbit build
- Output
- dist/
Advanced
12 / Code
Inline, block, numbered, diff and terminal
Each line is its own span.ln, so line numbers,
highlights and diff marks belong to the line instead of sitting on top of it.
The copy button copies the code without the line numbers.
Inline code sits in a sunken box with a subtle rule: run orbit deploy --prod,
then check ORBIT_TOKEN is set. Keys use Ctrl K,
and a match shows up as an inverted inline block instead of a highlighter.
export async function send(hook: Hook, body: string) { for (let attempt = 0; attempt < 5; attempt++) { const res = await fetch(hook.url, { method: "POST", body }); if (res.ok) return res; // back off: 200ms, 400ms, 800ms ... await sleep(200 * 2 ** attempt); } throw new WebhookError(hook.id);}
[[routes]]pattern = "/api/*"timeout = 10timeout = 30retries = 5service = "api-gateway"
orbit deploy --prod✓ build 1.8s✓ upload 0.4s✓ propagate 2.1slive at https://orbit.app → 310 pops
npm install @orbit/sdkpnpm add @orbit/sdkbun add @orbit/sdk13 / Lists
Square bullets, mono numerals, drawn checks
Bullets are squares too. Numbered lists use zero-padded mono numbers, so the alignment doesn't shift when a list reaches item 10.
Unordered
- Immutable, content-addressed builds
- Edge routing across 310 locations
- Automatic failover
- Per-route timeouts
- Zero-config TLS
Ordered
- Install the CLI
- Run
orbit initin your project - Link a Git repository
- Push to deploy
Checklist & plan states
- Reproduce the failing test
- Add retry with backoff
- Update the changelog
- Unlimited preview deploys
- SAML single sign-on
Ruled
- Create a project
- Connect a domain
- Invite the team
Description list
- Service
- edge-router
- Region
- us-east-1
- Commit
- 8f3a1c2
- Status
- Healthy
Blockquote
We moved 40 services in a weekend and nobody noticed. That was the point.
14 / Date picker
The calendar is a grid of shared cells
Typing is still the main way to enter a date. The field accepts
YYYY-MM-DD and the calendar is there to help. Arrow
keys move by day and week, PgUp
PgDn by month. Range pickers show presets first.
Field + popover
Type it, or pick from the calendar.
Inline
Range with presets
Presets come first, because nobody wants to click around a grid to pick “last 30 days”.
15 / Slider, stepper & segmented
A square thumb, and always a number beside it
Sliders are for rough values. Put a number field next to one, so people can type 37 instead of trying to drag to it.
- Slider
-
- Stepper
-
min 0 · max 12
- Segmented
- Built on native radios, so arrow keys and form values just work
16 / File upload
The one place a dashed line is allowed
A dashed line looks like a space waiting to be filled. Drag a file over it and the line turns solid accent. Errors show up on the file that caused them, not on the drop zone. Try dropping a file.
- pdfDone
q3-invoice-acme.pdf
- csvUploading
requests-sep-2026.csv
- movFailed
launch-video-final-v3.mov
17 / Progress & meters
Quantities as cells, loading as a stepped square
A progress bar shows how far along a task is. A meter shows a level against a limit. The spinner is a 4px square stepping around the edge of a box, with no arcs anywhere.
Progress
Approaching the monthly limit
Meter & steps
Spinner & loading
Indeterminate
18 / Avatars & activity
Square avatars, square presence, a literal timeline
Avatars are square like everything else. In a group they sit side by side and share borders, instead of overlapping like a stack of circles.
Sizes & presence
Group
In a row
Jo Rivera
jo@acme.dev · admin
Timeline
- 12:04:33
Deploy succeeded
edge-router · 8f3a1c2
- 11:58:10
Jo Rivera promoted a preview
- 11:40:02
p95 above 500ms in ap-south-1
Auto-resolved after 6 minutes.
- 09:12:45
Environment variable updated
19 / Layout primitives
Stack, cluster, grid, auto-grid, split
Five classes in boxy.css. Each one reads its gap
from a single custom property, --bx-gap, so you
pick a value from the space scale and never rebuild the layout yourself.
- .bx-stack
Vertical flow, one gap
-
010203
- .bx-cluster
A wrapping row
-
edgetlsroutingcacheobservabilitystorage
- .bx-grid
12 columns · 16 in industrial
-
span 8span 433span 6
- .bx-auto-grid
Fits tracks of --bx-min; no breakpoints
-
cellcellcellcellcell
- .bx-split
Side + main; wraps when main gets narrow
-
side · 200pxmain · fluid
20 / Agent & chat
Agent chat reads like a transcript
There are no chat bubbles. Tool calls look like log lines, with status, name, arguments and duration, and expand to show their input and output. Reasoning is collapsed and muted. An approval is the only point where the agent waits for a person. You can type in the composer below.
The webhook test is flaky in CI. Can you find out why and fix it?
Thought for 6s
Flaky suggests timing. The test posts to a mock that sometimes returns 503 on first boot. The sender has no retry, so any cold mock fails the run.
grep"send(" src/webhooks0.2s
src/webhooks/send.ts:4 export async function send(hook, body) src/webhooks/queue.ts:31 await send(hook, payload)
read_filesrc/webhooks/send.ts0.1s
{ "path": "src/webhooks/send.ts", "lines": [1, 12] }
Output · 12 lines
export async function send(hook: Hook, body: string) {
const res = await fetch(hook.url, { method: "POST", body });
if (!res.ok) throw new WebhookError(hook.id);
return res;
}
runnpm test -- webhooks4.8s
FAIL webhooks/send.test.ts ✗ delivers to a cold endpoint (503 Service Unavailable)
Found it. send() gives up on the first non-2xx response, and the mock endpoint returns
503 for about 300ms after boot1. I'll add a bounded retry with exponential backoff.
Run a command that writes to the working tree:
npm test -- webhooks --update-snapshots
21 / Combobox & multi-select
Type to filter, arrows to move, Enter to take
Focus stays in the input the whole time, and the highlighted option is
tracked with aria-activedescendant. The part of
each option that matches what you typed is shown inverted. In the multi-select,
chosen items become square tags inside the field, and
Backspace in an empty input removes the last one.
Try “eu” or “south”.
- Americas
- us-east-1 · Virginia
- us-west-2 · Oregon
- sa-east-1 · São Paulo
- Europe
- eu-west-2 · London
- eu-central-1 · Frankfurt
- Asia Pacific
- ap-south-1 · Mumbai
- ap-east-2 · Taipei
Backspace removes the last label.
- bug
- performance
- networking
- security
- documentation
- good first issue
22 / Kanban board
Columns share borders, and a dragged card gets a hard shadow
Drag cards between columns, or focus a card and press Alt with the arrow keys. The drop slot is dashed because it's an empty space waiting for a card. A column over its WIP limit gets a warning line under its header instead of a red background.
Rotate staging TLS certificates
Document route-level timeouts
Retry webhooks with backoff
p95 alert per route
Migrate cron to queues
Preview deploys for every branch
Square radio buttons
23 / Resizable panes
The divider is just the line
It's a 1px line with an invisible 8px hit area, and it becomes a 2px accent bar on hover, drag or focus. Arrow keys resize by 16px (64px with Shift). Enter or a double-click resets it.
export async function send(hook, body) { for (let attempt = 0; attempt < 5; attempt++) { const res = await fetch(hook.url, { body }); if (res.ok) return res; } }
$ npm test -- webhooks
✓ 12 passed
24 / Editable data grid
It works like a spreadsheet
Arrow keys move the selection ring. Enter, F2, a double-click or just typing starts an edit. Enter saves and moves down, Tab moves right, and Esc cancels. Edited cells get an accent corner, and the region column checks what you type.
| Row | Service | Region | Replicas | Memory MB | Owner |
|---|---|---|---|---|---|
| 1 | edge-router | us-east-1 | 12 | 512 | Jo Rivera |
| 2 | api-gateway | eu-west-2 | 8 | 1024 | Mina Kato |
| 3 | image-proxy | ap-south-1 | 4 | 2048 | Ada Okafor |
| 4 | webhook-fanout | us-east-1 | 2 | 256 | Aryan Ebrahimpour |
25 / Colour picker
A colour picker that tells you the contrast
It has a saturation and brightness field, a hue strip, a hex input and swatches. The readout also checks the colour against the page background. Picking a blue is only half the job. You also need to know whether text is readable on it.
Drag in the field or use the arrow keys on it; the hue strip is a native range input. The eyedropper button appears only where the browser supports it.
26 / Notification inbox
Unread items get a mark instead of a tint
The count on the bell uses the accent colour, because it's the one thing in the bar that needs attention. Unread items get a 6px accent square and full-strength text. Read items are muted. You can act on an item without opening it.
Notifications
- Today
- 12:31
webhook-fanout error rate is above 1% in us-east-1
- AO11:58
Ada Okafor mentioned you on ORB-204: “can you review the backoff?”
- AI11:40
Agent is waiting for approval to run a command
- Yesterday
- Tue
edge-router deployed to 310 locations
- JRTue
Jo Rivera assigned you ORB-219
27 / Blueprint details
Off by default, and no more than three per screen
Put these everywhere and they turn into clutter. They work best on hero sections, feature panels and empty states.
Grid substrate
8px squares at 5.5% ink. Element edges should line up with it.
Corner ticks
Mark two corners by default, and leave most cards without them.
Hatch fill
For placeholders and inactive areas. Boxy's version of the gray placeholder box.
Technical annotations
Small mono metadata is the easiest way to make a page look like a datasheet. Only use it for real values.