June 29, 2026
How I built Cognition Coffee using Devin
The features, the PRs behind them, and how I used Devin to build a Gatsby OS-style site.
Cognition Coffee is a concept for what Devin's community could be. I built it as a mock OS: a desktop of draggable windows that toggles into a normal arranged-pages site. It nods to PostHog.com's mock OS, to Devin's original pitch of cloud agents with their own VMs, and to the early-2000s internet cafes where the first developer communities formed.
The stack is Gatsby 5, React 18, TypeScript. Every page and post is a plain .tsx component registered in src/content/blog/index.ts and src/content/pages/index.ts, routed through gatsby-node.ts. No MDX, no CMS, no filesystem sourcing. The admin writes JSON; the live site is a Gatsby build.

The best way to argue for a Devin community strategy is to build the thing with Devin.
The build
OS mode and site mode
The default view is the OS. The Devin otter is the wallpaper under a faint CRT overlay; seven icons (Home, Menu, Blog, Community, About, Terminal, and a hidden scott.png) open draggable, resizable windows. A taskbar tracks them, with a clock and the OS/Site toggle.
PR #21 replatformed from Astro to Gatsby and added the window manager. PR #36 moved window lifecycle, z-order, and mode switching into one XState v5 machine in src/os/osMachine.ts. PR #23 skips the OS on mobile; PR #24 added the macOS traffic-light controls.
The first desktop was unusable. A pointer-capture bug ate icon clicks, so I shipped a broken desktop for a stretch before PR #49 fixed it.

Home page
src/pages/index.tsx is a hero, a short intro, and the list of sections, pulled from the same APPS registry (src/lib/apps.ts) that drives the desktop icons, so the home page and the OS never drift. PR #47 polished it; PR #62 fixed the mobile logo.

The Menu
The Menu is the site dressed as a coffee-shop order (src/content/pages/menu.tsx): a sticky category nav, photo-dominant cards, and a lightbox with a "What's Included" breakdown, customization options, and a special-instructions field. A quick-add button drops items into a cart scoped to the OS window. Data lives in src/data/menu.ts and is served from /api/menu so the admin can edit it live. PR #43 built the catalog; PR #58 gave it the DoorDash-style overhaul.
The cart leaked out of the window once. The floating button and toast were positioned against the browser viewport, so they sat over the taskbar until 968180b scoped them to the window.

Community
src/content/pages/community.tsx is a single-column editorial: a polaroid carousel of real community builders, animated counters for cities, events, and attendees, a wall of real tweets, the ambassador program, and an FAQ accordion. PR #46 overhauled the UI; PR #65 fixed the map and swapped AI-generated images for Unsplash photos.

About
src/content/pages/about.tsx is Ali's page: bio, social links, and work history from src/data/experience.ts as panel cards with mono dates. PR #10 set the shape, PR #44 the UI. It had a rough patch: 270bc62 deleted the page and the /about route, then ce6f1ef restored it with an Experience editor in the admin.
It rendered unstyled once, using Tailwind classes that weren't in the stylesheet. Build green, page broken. Agents don't always check that a class name resolves.
Terminal
src/components/Terminal.tsx is a fake UNIX shell with a virtual filesystem that mirrors the site: ls, cd, cat, open, tab completion, and arrow-key history. open menu.tsx opens the Menu in a new OS window. PR #40 built it; PR #57 added first-visit autoboot.

Games
Three open-source games run as their own OS apps: Snake, Space Invaders, and Pong. Each is vendored as-is under static/vendor/games/ and loaded in a same-origin iframe by src/components/GamePage.tsx, under a footer crediting the upstream repo. Because the frame shares the origin, it grabs keyboard focus on load and on click, so arrow and space keys reach the game instead of the window behind it. PRs #68–#70 vendored the games; #71 wired them in as apps; #72 listed them in the terminal filesystem; and #73 made them open windowed.

Blog and admin
Blog posts are .tsx components in src/content/blog/. src/templates/blog-post.tsx renders the admin-edited JSON, falling back to the static component when a post hasn't been touched. The admin at /admin is a password-gated TipTap editor backed by Cloudflare Functions that read and write JSON through the GitHub Contents API: posts, menu, work history, and logo upload. Each save commits to the repo and triggers a Cloudflare rebuild. PR #34 built it; PR #67 forced the admin background white.
Design system, tests, 404
The palette is warm canvas, near-black ink, and Devin blue as the only accent, with Geist for type. Tokens live in tailwind.config.js and src/styles/global.css. PR #25 set the palette; PR #33, #41, and #42 built and polished the component library. The OS shell has 30 Vitest tests (PR #50); 404.tsx redirects unknown paths home.
How I used Devin
I ran Devin Desktop to orchestrate local and cloud agents, and picked the model for each job.
- SWE-1.6, Devin's small model, took the one-line fixes.
- GLM-5.2 did most of the frontend. Free in Devin at the time and unexpectedly good at JSX, Tailwind, and layout. I stopped reaching for bigger models on UI once I saw it handle the shell.
- Kimi K2.6 got the vision work, anything that started from a screenshot. "Make this match the reference" is a different task than "write this function."
- Opus 4.8, 1M context came out for the rare job that needed the whole codebase at once.
For big changes I let one Devin Ultra coordinator fan out to subagents working in parallel. The UI wave is the cleanest example: PRs #41–#47 each took a different surface against the same token file. The cost is merge conflicts on shared files; next time I'd merge the design-system PR first.
A few habits mattered more than the model choice.
- Delegate from anywhere. I kicked off work from BART and from bed using the Devin integration with Poke and dictation with Wispr Flow. Most of my direction happened away from a desk.
- Brief up front, then let it cook. I told each agent to ask its questions before starting, so it could run without stopping every few minutes. A two-minute brief saves an hour of round-trips.
- Hand it the right references. Brian Lovin's site for the reading layout, Matt Palmer's Beautiful UI Libraries, the Impeccable skillset, and shadcn primitives kept the output from looking generic.
- Let Devin write its own subagent prompts. Mine were too vague and the child Devins wandered; its own prompts drew sharp file boundaries.
- Gate every PR. deslop caught AI tells — obvious comments, triple null-checks, debug logs — and a green
npm run buildplusvitestcaught class-name typos and missing imports before they reached the live site.
Deployment
Every push to main builds with Gatsby and deploys to Cloudflare Pages (PR #17). The live site is cognitioncoffee.co.
Feature map
| Feature | Where it lives | PR / commit |
|---|---|---|
| OS window manager and state machine | src/os/osMachine.ts, src/context/App.tsx | #21, #36 |
| OS desktop and wallpaper | src/components/Desktop.tsx, static/wallpapers/otter-desktop.jpg | #26, #28 |
| macOS-style window chrome | src/components/AppWindow.tsx | #24, #41 |
| Draggable desktop icons | src/components/Desktop.tsx, src/lib/apps.ts | #40, #49 |
| OS/Site mode toggle | src/components/ModeToggle.tsx, src/components/Wrapper.tsx | #21, #23 |
| Home page | src/pages/index.tsx | #47, #62 |
| Menu catalog, lightbox, cart | src/content/pages/menu.tsx, src/components/menu/*, src/data/menu.ts | #43, #58, 0c7f9c9 |
| Community page | src/content/pages/community.tsx, src/components/community/*, src/data/community.ts | #46, #65 |
| About page and Experience editor | src/content/pages/about.tsx, src/data/experience.ts | #10, #44, ce6f1ef |
| Terminal | src/components/Terminal.tsx, src/pages/terminal.tsx | #40, #57 |
| Games (Snake, Space Invaders, Pong) | src/components/GamePage.tsx, src/pages/{snake,space-invaders,pong}.tsx, static/vendor/games/* | #68–#71, #73 |
| Blog index and post template | src/pages/blog.tsx, src/templates/blog-post.tsx, src/content/blog/* | #12, #45 |
| Admin editor and API | src/pages/admin.tsx, src/components/editor/Editor.tsx, functions/api/* | #34, #39, 4a2a3c6, #67 |
| Design tokens and UI primitives | src/styles/global.css, tailwind.config.js, src/lib/tokens.ts, src/components/ui/* | #25, #33, #42 |
| Tests | vitest.config.ts, src/components/__tests__/* | #50, #49 |
| 404 redirect | src/pages/404.tsx | beb23aa |
| Brand and scott.png easter egg | src/lib/apps.ts, src/components/AppIcon.tsx, src/pages/scott.tsx, static/scott.png | #31, #32, 1492933 |
| Cloudflare Pages deploy | .github/workflows/*, package.json | #17, #38 |