Applies to all user-facing writing on the website (docs, marketing, blog). Internal code names are unaffected.
- The service that routes, schedules, and persists actors is the control plane. Never "engine", "server", or "orchestrator".
- A process running the user's code with the Rivet SDK is a worker. Never "envoy", "runner", "node", "compute", or "data plane".
- Never use "agent" as a deployment noun. Rivet ships agentOS and Actors is "where agents live"; the collision is unrecoverable.
- "envoy" never appears on the website. Envoy Proxy is a top-tier CNCF project. Internal code keeps
pegboard-envoy/envoy-client. - Rivet Compute is a live Rivet Cloud feature, documented at
/cloud/docs/compute/. Where prose must name the managed offering, it is Rivet Cloud. When describing what Rivet Cloud runs for the customer, say "your backend", never "your workers". - Rivet Cloud docs live at
/cloud/docs/. Dashboard links point athttps://dashboard.rivet.dev. - Positioning canon: the tagline is "Infrastructure for the agentic era." with the supporting line "Orchestrate agents. Operate their environment. Automate their work. Deploy what they build." The phrase "infrastructure for long-lived software" is retired.
- "Self-Host" names the section; "control plane" names the thing. Pages inside it say "deploy the control plane on Kubernetes".
- Do not rewrite blog or changelog posts to apply this terminology. They are dated records; dead links are handled by redirects.
- Guides are generated per product from one source. Never hand-edit a generated per-product copy; product variation enters only through the named slots (
requirements,env,snippet,caveats,verify). - If a guide needs a sixth slot, it genuinely forks. Do not widen the template further.
- Prerequisites go in a
## Requirementsblock above## Steps, never as Step 1. ## Stepsis an H2 wrapping<Steps>. Four to six steps maximum, each titled with an imperative verb.- Every command shows its expected output. This replaces a prose verification step.
- Budget roughly two sentences per step. Anything needing a paragraph of why belongs in
## Optionsor the concept docs. - Never restate shared reference. Ports, env vars, and configuration live on one canonical page each; guides link to them.
- Use tabs for variants (Rivet Cloud vs self-hosted, and the product switcher), never a forked page.
- Pin versions in every snippet. No
:latest. ## Next stepscarries at most three links.- The control plane is stateful, so serverless platforms are worker-only. Adding a platform means updating
deployMatrix.ts, which feeds both the sidebar andgetStaticPaths. - Platform support is uniform across all four products, including agentOS. agentOS runs inside actors and the actor supplies persistence, so it needs nothing extra from the host platform. Do not exclude it from serverless platforms.
- Worker guides inherit one shared architecture diagram from the template. Do not add a per-guide diagram; platform detail belongs in the steps.
- Diagrams are hand-authored inline SVG via the
creating-docs-diagramsskill, drawn inpine(sageinside ink panels). Not Mermaid.
To add or update icons, see frontend/packages/icons/CLAUDE.md.
The product wordmarks in src/images/products/*-logo.svg are white-on-transparent: the alpha channel is the mark, so the file carries no color of its own. They are always painted as a masked element via wordmarkMaskStyle (src/lib/product-accent.ts), never as an <img>.
- Never render a naked mark. A wordmark always rides inside its tile:
rounded-[34.375%]at the SVG's inset-ring geometry, filled ink or the product accent. A bare mark dropped on a light surface — an<img>withbrightness-0, an invert filter, or a raw mask onpaper— is the failure mode this rule exists to prevent. It reads as a black outline box and matches nothing else on the site. - The mark inside the tile is white, never cream. Cream is for text and fills inside ink panels; on a mark it reads as a dirty off-white against the pure-white Rivet badge in the header.
- Ink tile (
bg-ink) is the default: product-page hero lockups (ProductLockup),/docscards (DocsLanding), inline product mentions, and any product list on a light surface. - Accent tile (
ProductBadgeinsrc/components/ProductBar.tsx) is the colored variant: header dropdowns, mobile sheet, product bar label, talk-to-an-engineer. Every place that lists products rendersProductBadgerather than hand-rolling the geometry, so the lockup cannot drift. - One sanctioned tile-less case: on the homepage stack plates (
StackSection) the mark is painted white directly on the product-accent field. The plate is the background — it is not a naked mark. - Rivet Cloud has no wordmark. It takes the
faCloudglyph — white inside an accent tile whereProductBadgesupplies one, otherwise bare in ink, sized down so it sits level with the neighboring tiles rather than outweighing them (its own hero, and the careers grid). Do not invent a wordmark for it.
Integration entries in website/src/data/registry.ts display icons on the registry page and detail pages. Each entry uses either an image (SVG file path) or an icon (Font Awesome icon).
image(SVG file inwebsite/public/images/registry/): Use for products and companies that have their own logo (e.g. Docker, Vercel, E2B).icon(Font Awesome from@rivet-gg/icons): Use for generic/non-product items that don't have a brand logo (e.g. Filesystem, Browser, SQLite).
When adding a new product integration:
- Search for the product's official SVG logo. Try these sources in order:
https://simpleicons.org/icons/{name}.svg(then apply the brand color)- The product's website favicon or press kit
- Their GitHub organization avatar
- Save the SVG to
website/public/images/registry/{slug}.svg. - Use actual brand colors. Do not convert logos to white/monochrome. Logos display on a dark background, so avoid dark/black logos. If a logo is black-only, find the dark-mode variant.
- The carousel selector at the top of the registry page applies a monochrome filter automatically. The colored version displays in the main card and detail pages.
Import from @rivet-gg/icons. The full Font Awesome Pro library is available. Common choices for registry items:
faFloppyDisk- filesystem/storagefaGlobe- web/browser/networkfaDatabase- databasefaSqlite/faPostgresql- specific databasesfaBrain- AI/memoryfaDesktop- local/desktopfaCode- code/interpreter
- Always store docs code examples under
examples/docs/and render them with<CodeSnippet>. Do not add inline fenced code blocks to docs MDX files. - Type-check all TypeScript code blocks in
website/src/content/docs/**/*.mdxbefore release, because any failing snippet fails the website build. - Document
onStateChangeas read-only againstc.state; usevarsfor callback counters or derived runtime-only values. - Connect page cards and sidebar entries come from
frontend/packages/shared-data/src/deploy.ts.
- Include all required imports.
- Define all referenced variables and types.
- Avoid placeholders or incomplete code that cannot compile.
- Use
@nocheckonly when a snippet intentionally documents API not available on this branch yet.
-
Use
<CodeGroup workspace>for any example that spans multiple files (for exampleregistry.ts+client.ts). -
Follow these rules for workspace code groups.
-
Store every file under
examples/docs/and render each one with<CodeSnippet file="..." title="..." />inside the group. -
Treat files as real modules in the same directory and use relative imports (for example
import type { registry } from "./registry"). -
Do not split related multi-file examples into separate non-workspace snippets.
-
If any code block fails type checking, the build fails.
- Marketing headings and card titles use
font-medium(h1 heroes, section h2s, h3/h4 card titles, FAQ headings, price figures). Do not introducefont-normalheadings. font-normalremains correct only for deliberate de-emphasis: tablethde-bolding, quietdtlabels, and input-like UI (TypesenseSearch).- Hero h1s and section h2s use the class constants in
src/components/marketing/typography.tsx(tracking-[-0.015em], h1leading-[1.06]). Do not hand-writetracking-tighton headings attext-2xlor larger;tracking-tightstays acceptable ontext-baseand smaller card titles. - Manrope is the only marketing typeface; JetBrains Mono covers code, terminal commands, keyboard keys, and tabular numeric data only — never titles, labels, or captions. No serif headings on marketing pages; the Learn section's serif treatment is the only exception.
- Section labels are quiet sans (
EYEBROW_CLASSoreditorial/Eyebrow):text-sm font-medium text-ink-faint, sentence case (text-cream/60inside ink panels). The mono uppercase letter-spaced eyebrow is retired, as are numbered markers ("01/02", "Fig. NN") anywhere in marketing UI. Plate and panel captions useCAPTION_CLASS(sans, sentence case, no figure numbers).
- Marketing pages and docs are light: cool porcelain (
paper,#EFEFEF) with apaper-deepradial pooling bottom-left (.depth-wash) and a fine grain (.paper-grain). Warmth comes from warm-blackinktext, classical imagery, and oil-paint textures, never from synthetic color gradients. Do not use the creammattoken as a surface/background design element on light surfaces (panels, dropdowns, badges, plate frames); usepaper/paper-mid/whiteorink-tint neutrals instead.creamstays valid only as the off-white text/fill inside darkinkpanels, and never on a product mark — those are white (see Product Marks). Docs paint the same porcelain field, render prose viaProse surface="paper", and usepinefor the active sidebar/TOC selected state; only the Learn section keeps a dark shell, and no other page may introduce a dark base. - Dark
inkpanels (editorial/InkPanel) are reserved for code, terminal, screenshot, and data moments. Code and data plates stay flat ink; the oil-texture backdrop (textureSrc) is for editorial moments only (CTA colophon, 404). - Orange is the spark: at most one
accent/ember CTA per page. White text sits only onaccent-deep(#D63E00) orinkfills, never onaccent. Pine (#2E4034) is the structural color for links, eyebrows, diagrams, and selected states; sage (#93A286) replaces it inside ink panels. - No drop shadows on marketing cards or imagery; depth comes from
border-ink/10..25hairlines,bg-white/55card fills, andpaper-mid/paper-deeplayering (inside ink panels:border-cream/10..15). Shadows stay acceptable on functional overlays (dropdowns, tooltips, modals) and the header's glass inset highlight. - Buttons use the constants in
src/components/marketing/typography.tsx— metricrounded-md px-4 py-2 text-sm font-mediumfor all. Primary accent =PRODUCT_HERO_PRIMARY_BUTTON_CLASS(accent-deep, the page's one ember); primary ink =PRIMARY_INK_BUTTON_CLASS; the only secondary =PRODUCT_HERO_SECONDARY_BUTTON_CLASS(border-ink/15 bg-white/55, filled — the borderlessborder-ink/20ghost is retired); light-on-ink primary =bg-white text-ink hover:bg-white/90. Do not hand-write button class strings. ink-fainttext is for captions and metadata at 12px+; body copy usesink-softorink.