deepraster.com home page
deepraster.com
Project 4 · Product · teaching

DeepRaster

An interactive computer-graphics learning platform. Instead of a demo that shows the final image, each lesson reveals how the image is made: inputs, intermediate steps and decisions.

TypeScriptAstro 7 + MDXWebGPU / WebGL2SVG runtimeCloudflareVitest
190articles
7workspace packages
0JS on plain articles
CIsize budgets
What I built

Features

01Interactive lessons

Each article pairs a 2D lab with a 3D lesson you can step through, inspect and change.

02Own graphics engine

WebGPU and WebGL2 device backends behind one renderer, with a shared device pool.

03SVG diagram runtime

Turns static SVG diagrams into animated, validated, interactive explanations.

04Semantic timeline

Play, pause, seek and step over meaningful states, not just animation frames.

05Learning runtime

Deterministic lesson state; coordinated result, observer and inspector views.

06Astro site

MDX content with Zod-validated metadata, a prerendered search index, SEO tests.

07Performance budgets

CI fails the build if pages, search index or scripts exceed their limits.

08Content pipeline

Written authoring pipelines, asset validation, and a local article review server.

09Production ops

Cloudflare Workers static assets, LaunchDarkly observability with privacy-hardened replay.

Architecture

A layered monorepo: dependencies only point down

websiteAstro · MDX · delivery lessonscomposition layer learninglesson contracts diagramSVG runtime engineWebGPU · WebGL2 timeline coreids · math · types engine: no lessons, no Astro diagram: no WebGPU, no Astro timeline: no SVG, no WebGPU no cycles · no importing another package's src/ framework at the edge: reusable packages never import Astro or site CSS
The engines are reusable products, not website internals. A page with one SVG lesson must not load the WebGPU engine or unrelated lessons ("load only what is used").
Architecture decisions

What I chose, and what I didn't

DecisionRejectedWhy
Own engineThree.js / BabylonThe product teaches what engines hide: buffers, passes and state must be inspectable
Static-first Astro, islandsA single-page appArticles ship zero JS; demos hydrate on their own; strong Core Web Vitals
Semantic state, separate from visualsAnimation-driven lessonsSeek, step and replay are exact; views can't corrupt learning state
Deterministic lessons (inputs + seed + step)Free-running simulationsReproducible explanations, testable without a browser
Size budgets in CIChecking performance by eyeRegressions fail the build before users see them
WebGPU with WebGL2 backendWebGPU onlyModern path where available, still works everywhere
Spec with MUST/SHOULD + ADRsInformal conventionsContributors and AI agents follow the same boundaries
Feature · learning runtime

Meaning first, animation second

one clock semantic timeline ray-builtbox-testedintersection-testedshaded owns state transitions · explanations · checkpoints visual timeline interpolates between states · never mutates them lesson statef(inputs, seed,step index) no DOM · no GPU handles resultthe output image observerindependent camera inspectorselected details views observe state and own theirresources (SVG nodes, GPU buffers) moving the observer camera neverchanges the result or the algorithm
A step like intersection-tested is data; an opacity tween is only a view of it. Seeking reconstructs the semantic state first, then views evaluate their visuals for that time. That's the same "state vs view" split as Redux, or RobotLens's snapshots.
Feature · page performance

Zero JS by default, demos load only when seen

plain article static SVG HTML + CSS · 0 JS bundles demo article viewport islandnot started yet scroll ① IntersectionObserver: demo visible? ② fetch this lesson's bundle only ③ pick device: WebGPU → WebGL2 ④ start · cleanup via cancel()
Astro renders everything at build time and hydrates only islands. startWhenVisible() wraps an IntersectionObserver and returns a cancel function, so every observer, timer and GPU resource has a deterministic cleanup path.
Byte budgets, enforced in CI

Performance you can't accidentally lose

scripts/scale-check.mjs inspects the production build and fails it when a limit is crossed. Content can grow to hundreds of articles without the site getting slower.

  • Search: a prerendered JSON index, cached for an hour, instead of search text embedded in every page.
  • Topics page: at most 30 rows rendered.
  • Content: every article's metadata is validated by a Zod schema at build time.
  • Delivery: static assets on Cloudflare's edge; no server to scale.
LIMIT · BUILD FAILS ABOVE topics page HTML≤ 120 KB article page HTML≤ 80 KB search index JSON≤ 2 MB JS on a plain article0 bundles topics and article bars share a scale
Engineering results

What this project proves

0 JS

Static-first delivery

Plain articles ship no bundles; demos load per lesson, only when visible.

CI

Budgets as tests

Page, index and script sizes fail the build instead of degrading silently.

2×

Dual GPU backend

WebGPU and WebGL2 devices behind one renderer, with a device pool.

layers

Reusable packages

7 packages, one-way dependencies, the framework at the edge.

f(x)

Deterministic lessons

State from inputs + seed + step; views only observe; seek is exact.

190

Content at scale

Zod-validated MDX, authoring pipelines, asset validation, review tooling.

It's also where I practise explaining hard ideas simply. That's the same skill as mentoring engineers, and the reason my interview diagrams look the way they do.