DylanOS

A browser phone OS drawn entirely on a single p5.js canvas - a live lock screen, a generated-notification engine, gestures, a passcode flow, and hidden camera modes, all coordinated on one shared coordinate system.

Visit project

Product screens

Under The Hood

The page diagrams its own build - page shell, p5.js renderer, state modules, and notification generators.

Under The Hood

Generated Notifications

A per-source engine fills the lock screen with varied, in-character alerts on every visit.

Generated Notifications

One Canvas, Live

The status bar, notification cards, and phone frame are all drawn on a single p5.js canvas.

One Canvas, Live
Execution Snapshot

The strongest signal first, then the operating context around it.

Lead Signal

Single p5.js canvasRendering across a shipped frontend / creative engineering build.

Delivery Role

Solo build, developed with an AI coding assistant over a few days: the canvas rendering architecture, the input pipeline, the notification generator system, the state modules, and the surrounding case-study page.

Product Context

It is deliberately not a component library or a real operating system. It is a showpiece for a specific kind of front-end work - coordinating rendering, generated content, state, and input on a canvas - and for shipping something polished quickly with an AI coding assistant.

Generated by category

Notifications

One self-contained page

Surface

Launch Posture

The stack and feature set were shaped for production use, not just a polished demo.

Next.jsReactTypeScriptp5.jsCanvasInteraction Design

Build Narrative

A clean story from constraint to shipped outcome.

01

Problem

01

Most web interfaces are assembled from DOM elements and someone else's component library, which quietly hides how rendering, input, and state actually fit together. I wanted a build where none of that was given - where every pixel, gesture, and state transition had to be designed and coordinated by hand.

Constraint mapping
02

Build

02

DylanOS is a fake phone, built way too seriously. A React page shell loads a client-side p5.js renderer that draws the entire phone - status bar, notifications, quick settings, passcode pad, fake home screen, and camera - onto one canvas. A notification engine generates in-character alerts from dozens of fictional app sources, and a single input layer routes mouse, touch, drag, swipe, and keyboard into the simulation.

System design
03

Outcome

03

A polished, self-contained browser toy that doubles as a front-end engineering case study - proof of comfort with canvas rendering, input systems, and generated content, and of shipping quickly with AI assistance.

Production outcome

Framing

Defining the product and the operating constraints.

It is deliberately not a component library or a real operating system. It is a showpiece for a specific kind of front-end work - coordinating rendering, generated content, state, and input on a canvas - and for shipping something polished quickly with an AI coding assistant. I split the simulation into clear responsibilities - drawing, input, state, notifications, quick settings, passcode, fake OS, and camera - and kept one internal coordinate system for the phone. The notification generators are organized by source category so the feed feels alive, and the render loop pauses itself when the phone is not visible.

Systems Index

Next.js
React
TypeScript
p5.js
Canvas
Interaction Design
Animation

Key features in scope

A full phone lock screen with a live status bar, all rendered on one p5.js canvas
A generated-notification engine drawing from dozens of fictional app sources across categories
Gesture handling: drag down for quick settings, swipe to dismiss, swipe up into a passcode unlock
A fake home screen and app grid behind a passcode, plus camera photo, video, and AI modes with hidden surprises
Notification sounds and device haptics where the browser supports them
An accessibility foundation with ARIA descriptions, a live notification region, and keyboard handling

Role and product posture

Role: Solo build, developed with an AI coding assistant over a few days: the canvas rendering architecture, the input pipeline, the notification generator system, the state modules, and the surrounding case-study page.
Category: Frontend / Creative Engineering

Engineering

Building the core system and choosing where to be opinionated.

DylanOS is a fake phone, built way too seriously. A React page shell loads a client-side p5.js renderer that draws the entire phone - status bar, notifications, quick settings, passcode pad, fake home screen, and camera - onto one canvas. A notification engine generates in-character alerts from dozens of fictional app sources, and a single input layer routes mouse, touch, drag, swipe, and keyboard into the simulation.

Systems Index

Next.js 15
React 19
TypeScript
Tailwind CSS v4
p5.js
Motion
Next.js page shell (RSC)
N/A - no persistence

Architecture choices

React Server Component page shell that loads the p5.js renderer only on the client, so the canvas runtime never evaluates during server rendering
One p5.js canvas that draws the whole phone on a single internal coordinate system while the page scales the outer frame responsively
Notification engine with a manager, grouped-notification models, and generators organized by category - development, finance, social, productivity, lifestyle, and more
State modules for authentication, quick settings, passcode, fake OS, camera, and menu bar, kept as separate concerns
One input layer that funnels mouse, touch, drag, swipe, and keyboard events through a shared handler without hijacking normal page scroll
Performance guards: assets and icons preload up front, and the draw loop pauses when the phone is off-screen or the tab is hidden

Key decisions

Render the entire interface on one canvas instead of the DOM, so layout, hit-testing, and animation share one coordinate system rather than fighting CSS
Dynamically import p5.js so server rendering stays clean and the canvas runtime is strictly client-side
Model notifications as a generator system organized by category, so the feed stays varied and in-character instead of a fixed list
Pause rendering the moment the phone is off-screen, so an always-animating canvas never taxes the surrounding page

Hardening

Turning the build into something resilient enough to matter.

A polished, self-contained browser toy that doubles as a front-end engineering case study - proof of comfort with canvas rendering, input systems, and generated content, and of shipping quickly with AI assistance.

Systems Index

Demonstrates front-end range beyond typical app work - canvas rendering, an input pipeline, and generated content coordinated by hand
Shows systems thinking in a small space: clear module boundaries, a single coordinate system, and deliberate performance guards
Evidence of shipping something polished and complete fast with an AI coding assistant
Memorable and self-explaining - the same page that runs the phone also diagrams how it was built

Results after shipping

Runs in production as a self-contained interactive page: lock screen, generated notifications, quick settings, passcode unlock, a fake home screen, and camera modes with hidden surprises
The notification engine produces varied, in-character alerts across dozens of fictional sources on every visit
Ships an under-the-hood writeup on the same page that diagrams the rendering, state, input, and performance model

Constraints

Everything is drawn on one canvas, so there is no DOM to lean on for layout, focus, or hit-testing
An always-animating canvas had to stay light enough not to degrade the surrounding page
Input had to support mouse, touch, drag, swipe, and keyboard without hijacking normal page scroll
Accessibility on a canvas UI has no free semantics - ARIA descriptions and a live region had to be added deliberately

Lessons

What the build taught me.

01

Rendering a full UI on a canvas trades CSS layout for total control - and makes you build hit-testing, focus, and accessibility yourself

02

A generator-per-source model keeps synthetic content feeling varied far better than a static list

03

Small performance guards - off-screen pause, asset preloading - matter a lot for an interface that never stops drawing

04

Explaining the architecture on the page itself turns a toy into a credible case study

Retrospective

With more time I would separate the state boundaries further before exposing any public API, bring the canvas UI closer to full DOM-equivalent screen-reader semantics, and replace manual regression checks with an automated browser-interaction test suite.