Creative Coding is organized around a deliberate three-layer architecture that keeps creative implementation, experiment registration, and URL routing completely separate from one another. This separation means you can reorder, rename, recategorize, or add a sketch by touching a single file — and the dashboard, URLs, and previews all update automatically without any boilerplate. The decision is formally captured inDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/hetari/creative-coding/llms.txt
Use this file to discover all available pages before exploring further.
docs/adr/0001-decouple-sketches-and-dynamic-routing.md.
Annotated Directory Tree
The Three Layers
Layer 1 — Sketch Implementations (src/sketches/)
Every creative coding experiment lives in its own domain folder under src/sketches/. A typical sketch folder contains an index.vue component that uses one of the lifecycle composables (usePixiApp, useP5, useGsap) to mount its canvas. More complex sketches also include GLSL shader sources (.vert / .frag), texture assets, and sketch-specific math helpers — all colocated together so the entire implementation is self-contained.
This directory is never touched by the router. Vite imports sketch components lazily via dynamic () => import(...) expressions declared in the central registry, so the file tree here can grow freely without affecting URL generation or dashboard layout.
Layer 2 — Central Registry (src/config/sketches.ts)
The SKETCHES array is the single source of truth for every experiment in the playground. Each SketchMeta entry defines:
The registry also exports two helper functions used by the catch-all router:
getSketchByPath(path) resolves a leaf sketch by its URL path, and isCategoryPath(path) determines whether a path matches a category prefix so the router knows to render the category dashboard instead.Layer 3 — Routing Shell (src/pages/)
src/pages/ intentionally contains exactly two files and is never modified when adding sketches:
index.vue— Renders the root dashboard. Reads theSKETCHESregistry to build a grouped grid of sketch cards, each showing either a lazy iframe preview or a static image preview.[...all].vue— A catch-all route seam powered byvue-router/auto-routes. It watchesroute.path, consults the registry, and dynamically resolves one of three outcomes:- Leaf sketch — Lazy-loads and mounts the sketch component found by
getSketchByPath. - Category dashboard — Renders
IndexPagefiltered to the matching category whenisCategoryPathreturnstrue. - 404 fallback — Shows a styled “Page Not Found” screen with a link back to the dashboard.
- Leaf sketch — Lazy-loads and mounts the sketch component found by
src/config/sketches.ts does.
Adding a New Sketch
The full step-by-step walkthrough for creating a sketch, registering it, and choosing a preview mode is covered in the Adding a Sketch guide. In summary, the two-step process is always:- Create
src/sketches/<category>/<name>/index.vuewith your canvas implementation. - Append one
SketchMetaentry to theSKETCHESarray insrc/config/sketches.ts.
ADR: Decoupled Architecture
The three-layer separation was a deliberate architectural decision recorded indocs/adr/0001-decouple-sketches-and-dynamic-routing.md.
The problem it solved: In the original design, src/pages/ carried two conflicting responsibilities — file-based route generation and creative implementation. This caused three compounding issues:
- Numeric folder prefixes leaked into URLs. Folders like
000-learn/were required for sorting, butunplugin-vue-routerbaked the prefix directly into the URL path (/shader/000-learn). - Dummy
index.vuefiles proliferated. Every category directory (gsap/,gsap/footer/,shader/) required an emptyindex.vuesolely to render a category card on the dashboard. - Shader binaries mixed with route definitions. GLSL
.frag/.vertfiles and canvas rasterizers lived directly inside the route tree, makingsrc/pages/a confusing hybrid of infrastructure and implementation.
src/sketches/, centralizing metadata in src/config/sketches.ts, and reducing src/pages/ to a static two-file dynamic shell, the playground achieved clean URLs (e.g. /shader/learn), zero page boilerplate, isolated shaders, and a single well-known edit location for all sketch changes.