Skip to content
Websites for developer tools: what works (research for the site)

Websites for developer tools: what works (research for the site)

  • Date: 15 October 2026
  • Lane: the public web. The landing pages and docs of terminal and developer tools that developers praise, their source where it is open, and well-known write-ups. Used for decision 0021, the design of this project’s site.
  • Method: a script drove headless Chrome over the DevTools protocol, at desktop size (1440 × 1800) and phone size (390 × 844, at 2×, with touch), with the cache off. For each page it recorded every request and its size, took a screenshot, read the fonts, colours and contrast, pressed Tab to see the focus style, scrolled to the bottom, and counted animation frames at the top, at the bottom and under reduced motion. It also searched each page’s own scripts for reduced-motion, IntersectionObserver and visibility handling. Where the source is public, I read it.
  • Clean-room: this note describes what the sites do, in our own words. It copies no code, art or text, and the site copies nothing from them.
  • Each weight is one run on one network, so treat the numbers as rough. Headless Chrome drew some WebGL heroes empty; I say where. Anything I could not confirm is marked UNVERIFIED.

Summary

The pages developers praise share a few habits. The first screen shows the product: for a terminal tool, a terminal. There is one install command to copy, and at most two calls to action. Motion is an extra with a still twin: it stops under reduced motion, off screen and in a hidden tab. The page stays light, because weight comes from PNG screenshots and autoplay video, not from code. The landing page and the docs share one domain, one header and one search.

No site we studied offers a visible pause button for its looping hero, which WCAG 2.2.2 asks for. And no common web font draws braille at the width of its Latin letters, so braille art in page text needs a font of its own.

What we take, and how, is in section 9.

1. Sites read

All read on 15 October 2026.

SitePagesWhy
Ghosttyhome, docs, config reference, website source (MIT)A terminal; ASCII art hero
Charmhome, librariesTerminal tools with a strong look
Warphome, docsA terminal
Zedhome, docsAn editor; keyboard-first
Bunhome, docsA CLI with a famous install line
Astro and StarlightAstro, Astro docs, Starlight, Starlight docs, Starlight sourceLight pages; a docs theme
Linearhome, docsRestraint and type
Vercelhome, docsA three.js hero with a still twin
Tailwind CSShome, docsA hero that teaches
Raycasthome, developer docsA polished launcher
Fly.iohome, docsIllustration; an agent prompt to copy
OxidehomeMany small ASCII animations, used to explain
ertdfgcvb Playplayground, play.core source (Apache-2.0)The open engine behind Oxide’s ASCII
OpenCodehomeA terminal agent’s site, all monospace
terminal.shophomeAn SSH product whose page is its command
Nous ResearchhomeOne colour and WebGL dither
GitHubhome, how the globe was builtWebGL done with care, written up

Checked briefly: Stripe, Poolside, Amp, Cursor, Factory and Evervault.

2. Page weight

Transfer size and number of requests, at first load and after scrolling to the bottom.

SiteDesktop, first loadDesktop, scrolledPhone, first loadWhere the weight is
Starlight134 KB / 22138 KB / 24115 KB / 14No web fonts; 24 KB of JS
terminal.shop218 KB / 18218 KB / 18324 KB / 22Fonts and a little JS
ertdfgcvb Play225 KB / 16225 KB / 16–A console font
Astro330 KB / 24490 KB / 35318 KB / 189 KB of JS; lazy images
Ghostty584 KB / 29584 KB / 29564 KB / 27A 285 KB sans font; frames in the HTML
Bun801 KB / 652.0 MB / 107753 KB / 63A 727 KB video below the fold; analytics
Oxide1.0 MB / 921.8 MB / 1001.2 MB / 90Photos, with tiny placeholders
Zed1.9 MB / 838.6 MB / 2471.9 MB / 61A streamed demo video
Fly.io2.3 MB / 292.7 MB / 411.8 MB / 28A payment library and analytics on the landing page
Raycast2.6 MB / 12841.7 MB / 3074.2 MB / 123PNG screenshots of 4–5 MB each
Vercel2.7 MB / 1323.1 MB / 1411.1 MB / 771.8 MB of JS
Linear2.8 MB / 4123.0 MB / 4502.1 MB / 321317 JS files
Tailwind CSS6.2 MB / 896.5 MB / 1115.9 MB / 72PNGs, and 1.2 MB of fonts
Nous Research7.9 MB / 1137.9 MB / 1277.4 MB / 108Images and fonts
Charm8.5 MB / 4712.4 MB / 4830.8 MB / 47Autoplay video, fetched twice on the phone
OpenCode10.2 MB / 2910.2 MB / 2910.2 MB / 29One 9.9 MB video
Warp29.0 MB / 17729.3 MB / 20829.2 MB / 17526 MB of PNG

For scale, the whole of three.js r170 as one minified module is 692 KB, or 171 KB with gzip (jsDelivr). Hextra’s search library, FlexSearch, is 15 KB with gzip.

The heavy pages are heavy because of pictures and video, not code.

3. Docs at a glance

DocsEngineSearchShortcutSame domain and header as the landing page
Ghosttyownnone: the config reference tells you to use the browser’s find–yes
BunownPagefind/yes
StarlightStarlightPagefindCtrl/Cmd+Kyes
AstroStarlightAlgolia DocSearchCtrl/Cmd+Kno: a subdomain with another header
WarpStarlightPagefind and an AI chatCtrl/Cmd+Kno: a subdomain
ZedmdBook, own themebuilt inSyes
Tailwind CSSownAlgolia DocSearchCtrl/Cmd+Kyes
Vercelownown command menu and Ask AICtrl/Cmd+Kyes
Linearownownnone shownyes
Fly.ioMintlifyMintlifyCtrl/Cmd+Kno: moved to another platform
RaycastGitBookGitBookCtrl/Cmd+Kno
Charmnonenone–no: libraries link to GitHub READMEs
Hextra (ours)HugoFlexSearch; the index loads when the dialog first opensCtrl/Cmd+K and /–

An llms.txt, a plain list of the docs for coding agents, answered at Warp, Zed, Bun, Linear, Vercel, Raycast’s developer docs, Fly.io and Amp. Ghostty, Astro, Starlight, Tailwind CSS and OpenCode had none.

4. Site by site

4.1 Ghostty

  • Hero. The first screen is one terminal window on near-black. It shows the ghost mascot as animated ASCII art, 100 columns by 41 rows, in blue and light grey. Under it are one sentence and two buttons: Download and Documentation. The window’s buttons match the visitor’s platform.
  • How the art is made (the script and its README). A short 3D-rendered video goes through ffmpeg at 100 columns and 24 frames a second. Each frame is squashed by the font’s aspect ratio, about 0.44. Each pixel is sorted by colour into blue, white or empty, and its brightness picks a character from a 10-step ramp. The result is 235 text frames that ship inside the page.
  • Motion (the component). A frame every 31 ms, about 32 a second. It starts only when the page is visible, pauses on window blur, and shows one still frame under reduced motion. The art is hidden from screen readers.
  • Docs. A left tree, breadcrumbs, “on this page”, an edit link and copy buttons. No search.
  • Weak points. The server HTML’s <main> is empty: without JavaScript the home page is blank. There is no h1 and no skip link.
  • Works: the product is a terminal, so the hero is a terminal, done with care. Avoid: a page drawn only by script, and docs without search.

4.2 Charm

  • Hero. A full-screen violet WebGL scene with 3D blobs, a featured product card with a terminal video, and library cards, each with a mascot and a looping terminal recording.
  • Motion. The WebGL background never stops, also at the bottom of the page and under reduced motion. Three videos autoplay.
  • Docs. None on the site: libraries link to their GitHub READMEs.
  • Accessibility. No lang attribute and no <main>. The first Tab lands on a link with no visible focus.
  • Works: strong personality, and each library shown by its real terminal output. Avoid: tens of MB of video, motion that ignores the reader, and docs that leave the site.

4.3 Warp

  • Hero. A light “engineering drawing” look: dotted grid paper, margin notes and captioned figures. “Figure 1” is a live grid of cells changing state, like a system diagram.
  • Motion. The grid drops to about 1 frame a second off screen and to none under reduced motion. The site plays sounds, and its mute toggle is the first thing a keyboard user meets.
  • Weight. 29 MB, 26 MB of it PNG.
  • Works: a live diagram that explains the product, and motion that stops when unseen. Avoid: multi-MB PNGs, and sound.

4.4 Zed

  • Hero. A centred headline, a Download button and a “Clone source” button, each with a one-letter key chip, then a large editor mock-up built in HTML. Zed served two different home pages across runs; UNVERIFIED whether that is a test.
  • Type. A serif for headlines, a “duospace” face that reads like mono for body text, and its own mono for code.
  • Docs. Same domain, mdBook with Zed’s theme; press S to search.
  • Accessibility. A strong focus ring. The key chips are only 2.2:1 contrast.
  • Works: keyboard signals everywhere, and the product as real UI. Avoid: low-contrast key chips.

4.5 Bun

  • Hero. On the left, a release eyebrow in mono, a heavy headline, then “Install Bun” with a one-liner, a $ prompt in the accent colour, a copy button, OS tabs and a “then follow the quickstart” link. On the right, a benchmark with a “reproduce” link to its source.
  • Motion. Scroll reveals exist only when motion is allowed, and the observer stops after each reveal. A terminal demo types, or shows all its lines at once under reduced motion. A video demo pauses below 30 % visibility. Prefetch is off under Save-Data, on slow connections and under prefers-reduced-data.
  • Docs. Same header; Pagefind with /; “Copy page”; an llms.txt.
  • Accessibility. A skip link first, and a 2 px focus ring in the accent colour.
  • Works: the first screen shows the product working, and every claim links to the docs. Avoid: analytics weight.

4.6 Astro and Starlight

  • Astro. A centred headline, a Get Started button and the create command in a mono pill with a copy icon. 330 KB and 9 KB of JS. Its docs are on a subdomain with another header.
  • Starlight. The lightest site measured: 134 KB, no web fonts. An inline script in the head sets the theme before the first paint, so dark mode never flashes (ThemeProvider). Search lives in a native <dialog> and loads at idle time (Search). Code blocks have terminal frames, synced package-manager tabs and copy buttons. A skip link goes to the title.
  • Works: docs chrome that is light and accessible by default. Avoid: a generic hero nobody remembers.

4.7 Linear

  • Hero. A large left-aligned headline, then a big product mock-up built in HTML on a soft glow.
  • Type. One sans for everything, and a mono for small captions and code chips.
  • Weak points. 412 requests. Some grey text is 3.1:1. 76 CSS animations still run under reduced motion, and one phone capture showed a blank first screen behind an entrance animation.
  • Works: restraint, and the product as the hero. Avoid: grey text under 4.5:1, and content hidden behind entrance animations.

4.8 Vercel

  • Hero. A three.js scene of a container on a crane hook. A still image of the same scene shows first.
  • Motion. About 8 frames a second at the top and none off screen. Under reduced motion it creates no WebGL context at all; the still image stays.
  • Docs. Same domain, a command menu on Ctrl/Cmd+K, Ask AI and an llms.txt.
  • Works: heavy 3D with a matching still twin and a real stop. Avoid: 1.8 MB of JS on a marketing page.

4.9 Tailwind CSS

  • Hero. A giant headline on grid paper. Faint mono labels above each element list the classes that style it: the page annotates itself with its own code. Search sits in the hero.
  • Motion. A loop at 60 frames a second at the top, at the bottom and under reduced motion.
  • Works: a hero that teaches the idea at a glance. Avoid: 1.2 MB of fonts, and a loop that never stops.

4.10 Raycast

  • Hero. A large WebGL scene (empty in headless Chrome), a Download button with a Homebrew line, and a macOS desktop mock-up of the launcher.
  • Weak points. 42 MB after scrolling, mostly PNG. No header, main, nav or footer landmarks. Developer docs on GitBook, on a subdomain.
  • Works: a polished mock-up of the real app, and a path for developers. Avoid: huge PNGs and missing landmarks.

4.11 Fly.io

  • Hero. A hand-drawn illustration, a serif headline, “Start for Free”, and a second button that copies an onboarding prompt for your coding agent.
  • Weak points. A payment library and analytics on the landing page. Docs moved to Mintlify on a subdomain. A cookie banner takes the first Tab stops.
  • Works: a distinct voice, and a call to action for people who work with agents. Avoid: docs on another platform with another look.

4.12 Oxide

  • Hero. A small terminal panel types a login and some commands. A leader line joins it to a photo of racks, captioned like a figure. ASCII shading glows behind.
  • Technique. Each ASCII piece is a <pre> driven by play.core, hidden from screen readers, with an invisible <pre> of dots beside it that measures the cell size. Photos load as tiny blurred placeholders and fade into the full image.
  • Works: ASCII that explains the system rather than decorates it, and mono labels that read like a datasheet. Avoid: a cookie banner over the hero.

4.13 ertdfgcvb Play and play.core

  • Technique (text renderer, run loop). A program is a function called once per cell, returning a character and a colour. The text renderer keeps the last frame and rebuilds only the rows that changed, one innerHTML string per row, with runs of the same style in one span. Cell size is measured once, so circles come out round in character space. The frame rate is capped at 30.
  • Works: a simple model, and diffs by row. Avoid: taking its layout as a model; it is an art tool.

4.14 OpenCode, terminal.shop and Nous Research

  • OpenCode. A pixel-block wordmark, an install box with tabs for six package managers, and features listed like a man page. One 9.9 MB video, which also plays under reduced motion.
  • terminal.shop. The page is numbered lines like an editor buffer: the SSH command, then the server’s host key so you can check it. 218 KB. No real headings or landmarks.
  • Nous Research. One electric blue, WebGL dither and retro condensed type. It respects reduced motion and the visibility of the tab, but weighs 17 MB on a phone after scrolling.

4.15 Others, briefly

  • Stripe. A WebGL ribbon that keeps about 140 frames a second under reduced motion.
  • Evervault. Many small WebGL canvases, together about 650 frames a second, still about 520 under reduced motion.
  • Poolside. A terminal mock-up hero; motion drops to about 2 frames a second under reduced motion.
  • Amp. 575 requests; respects reduced motion.
  • Factory. A 20 MB video. Cursor. 6.3 MB at first load.

5. Write-ups

  • Evil Martians, a study of 100 developer-tool landing pages (2025). Centred heroes dominate. The hero visual depends on the product’s maturity: real UI, code, or abstract art before launch. Use two calls to action, one product-specific and one for developers (docs, source). Lead features with problems, and end with a full-width call to action. Their list of conversion killers adds: vague words, vague buttons and a crowded first screen.
  • GitHub, the Copilot CLI’s animated ASCII banner (2026). Frames are plain text, and each character has a role (border, eyes), mapped to ANSI colours for light and dark themes. The banner is skipped for screen readers and never blocks start-up. Most of the work went into terminal differences and accessibility.
  • GitHub, how the globe was built (2020). three.js, no textures: about 12,000 dots in one instanced draw call, antialiasing off, a light SVG placeholder that cross-fades into the canvas, and a frame-time watch that lowers the pixel ratio and the detail on slow machines.
  • Alex Harri, ASCII characters are not pixels (2026). One brightness per cell blurs edges. Sampling the shape of each cell and picking the nearest glyph shape is much sharper, and fast enough on a GPU.
  • WebGL ASCII, offscreencanvas.com. Render a scene, cut it into cells, and in the fragment shader pick a glyph from an atlas drawn with canvas 2D, ordered from light to dense.
  • Maxime Heckel, dithering and retro shading for the web (2024). Ordered and blue-noise dithering as one post-processing pass in a shader.
  • three.js. The AsciiEffect example reads pixels back from the GPU and rewrites an HTML table every frame: easy, but too costly for a hero. The manual says to dispose of geometries, materials and textures by hand, to cap the pixel ratio, and to render only when something changes. WebGLRenderer has failIfMajorPerformanceCaveat, which refuses software GL, so a slow machine can keep a still image.
  • web.dev, prefers-reduced-motion. Build without motion first, and add it only when the reader has no preference. In script, listen for changes to the setting.
  • MDN, Page Visibility and Intersection Observer. Browsers slow background tabs, but your own timers and loops need stopping by hand. Observers replace scroll handlers.
  • WCAG 2.2.
  • Hextra, our docs theme (source). Search is a native <dialog> on Ctrl/Cmd+K or /, and the index loads on first open. The base template has a skip link. Its asciinema shortcode loads the player from a CDN at @latest, so we do not use it.

6. Braille in web fonts

A braille hero drawn as page text needs every braille cell to be exactly as wide as a letter. A test page drew 20 braille cells and 20 Latin letters, at 16 px, in nine monospace fonts as Google Fonts serves them: JetBrains Mono, IBM Plex Mono, Geist Mono, Fira Code, Source Code Pro, Roboto Mono, Space Mono, Martian Mono and Noto Sans Mono.

  • Braille. None of them drew braille. Every one fell back to the system’s braille font, which was about 14 % wider: 218.8 px against 192 px. Braille columns would drift away from the text around them.
  • Blocks and box lines. Most fell back to the system mono. Geist Mono and Fira Code drew them at the right width.

We checked the full JetBrains Mono 2.304 release file ourselves: it has the box lines, blocks, arrows and state glyphs the launcher uses, and no braille.

7. Patterns, ranked

  1. Show the product first. For a terminal tool, the hero is a terminal: Ghostty, Oxide, Bun, OpenCode, Poolside, terminal.shop. Linear and Zed do the same for a GUI.
  2. One install command to copy, with a link to the next step: Bun, Astro, OpenCode.
  3. Two calls to action at most: Ghostty, Bun, Astro, Starlight.
  4. Motion with a still twin, stopped under reduced motion, off screen and in a hidden tab: Vercel, Warp, Bun, GitHub, Ghostty. Not Charm, Tailwind CSS, Stripe or Evervault.
  5. A pause button for a looping hero. None of the sites has one.
  6. A light page. Under 1 MB is normal for the best: Starlight, Astro, Ghostty, Bun.
  7. One domain, one header, one search for the landing page and the docs: Bun, Starlight, Zed, Vercel, Tailwind CSS, Linear.
  8. Keyboard first: / and Ctrl/Cmd+K, key chips, copy buttons on every code block.
  9. Mono as a voice, not as body text: mono for commands, labels and captions, and a readable face for paragraphs (Bun, Linear, Oxide, Zed).
  10. Pictures that explain: Warp’s live diagram, Oxide’s figures, Tailwind’s self-annotation.
  11. Evidence over claims: Bun’s “reproduce” link, terminal.shop’s host key.
  12. Accessibility basics: a skip link, visible focus, landmarks, art hidden from screen readers, and grey text at 4.5:1 or more.
  13. Dark and light, following the system, with no flash: Starlight, Bun, Vercel.
  14. Content in the HTML, with the art added on top; never an empty page without script.
  15. Docs for agents: llms.txt and “copy page as Markdown”.

8. Rendering a glyph field

WaySeen atGoodCosts
Text frames made beforehand, swapped in a <pre>GhosttyTiny at run time; crisp; one frame is the stillFixed art; payload grows with frames
A live text grid, rebuilt by rowplay.core, OxideCrisp; the font’s own glyphsCost grows with cells and frames; braille falls back (section 6)
Canvas 2D, one fillText per cellplay.coreNo page churnThousands of calls a frame
three.js AsciiEffectthree.js exampleTurns any scene into textA GPU read-back and a table rewrite every frame
One shader pass with a glyph atlasoffscreencanvas, CodropsOne draw call; all on the GPUThe atlas needs the font, or its own drawing
Points or instances, one per cellthe GitHub globeCells can move in 3DMore vertex work

9. What we take for our site

Decision 0021 has the choices and their reasons. In short:

  • The hero is the launcher, live in the page with the demo command’s sample data, built from the same rules as the real screens. Without script, the page shows the real render, docs/images/sessions.svg.
  • The three.js piece is a field of braille cells with the welcome mark’s three strands running through it. It is points in one draw call, each drawn as a braille glyph from an atlas the page draws itself, so no font is needed. It loads last, only with motion on, WebGL on the GPU (failIfMajorPerformanceCaveat), data saving off and the stage on screen. It stops off screen and in a hidden tab, and is freed when the page goes away.
  • A still twin everywhere: the welcome mark as text in the HTML, and the launcher’s real render.
  • A visible pause button for all the page’s motion, and a motion switch in the footer that works like the launcher’s ui.motion.
  • A braille font of our own (2 KB), drawn to the monospace face’s cell, so braille lines up with text (section 6).
  • One domain, one header, one search: the landing page uses the docs’ header and Hextra’s search. Every link between pages stays on the site, and a check enforces it.
  • Light: self-hosted fonts cut to what the site uses, no images but the launcher’s SVG, no analytics, no cookies, and no request to anyone else.
  • An llms.txt for coding agents.
  • Not taken: autoplay video, PNG screenshots, sound, scroll-triggered reveals of content, and anything that only works with script.

10. Not verified

  • How Raycast, Zed and Charm draw their WebGL: their scenes were empty or minimal under software GL, and their sources are not public.
  • Whether Zed’s two home pages are a test or depend on the browser.
  • The full Codrops article on shape-aware ASCII in three.js: only its listing was read.
  • The weights are single runs. Our own site’s numbers are in decision 0021.

View the source of this page Suggest a change