martian-ui: The Game Engine Hiding in the DOM: Inside Martian UI

How Cheng Lou’s experimental toolkit abandons declarative state for continuous physics, treating the browser like a low-level rendering target.

7 min read · chenglou/martian-ui

An extreme close-up of a sharp metal drafting compass drawing a perfectly smooth, continuous arc across the page. Beneath the compass point is a strip of paper tape showing a jagged, erratic seismograph reading.
Martian UI decouples the physical clock from the logical clock, smoothing out erratic hardware refresh rates.
Key Takeaways

The web has spent a decade perfecting the reactive paradigm. State A transitions to State B, and the framework figures out the rest. But for developers chasing the frictionless, sub-pixel perfection of native macOS or iOS interfaces, this declarative playbook often feels like driving a sports car through molasses. Martian UI, an experimental toolkit authored by React Motion creator Cheng Lou, throws out the declarative playbook entirely.

It reveals a slightly uncomfortable truth: to achieve true, uncompromised fidelity, you must treat the browser not as a document viewer, but as a low-level input stream and rendering target. It is a continuous simulation, a “game loop” for the web, and a forensic textbook of invisible browser quirks.

The Death of the Event Listener

In a standard web application, logic fires directly inside an `onClick` or `mousemove` callback. When a user interacts rapidly, or when multiple inputs collide in a single 8ms window, the resulting state updates often conflict, leading to dropped frames or jittery animations. Martian UI’s core engine, located in `src/core.ts`, addresses this by fundamentally changing how inputs are handled via the `makeScheduler` function.

The traditional callback race condition versus Martian UI's buffered scheduler approach.

Instead of executing logic immediately, the scheduler decouples the input from the render cycle. It buffers all incoming events—clicks, touches, keystrokes—into a queue and processes them holistically during a single `requestAnimationFrame` (rAF) loop. This allows the system to resolve conflicting inputs before anything hits the screen, ensuring that a frantic user interaction doesn't tear the UI apart.

Decoupling the Physical Clock

A persistent headache in web animation is the hardware clock. Animations tied directly to `requestAnimationFrame` behave differently on a 60Hz monitor than they do on a 120Hz ProMotion display. Martian UI’s physics engine, `src/spring.ts`, solves this by severing the link between the physical simulation and the logical render clock.

The engine runs multiple simulation steps per frame if necessary, defined by `msPerAnimationStep = 6`. This means that regardless of the monitor's refresh rate, the physics simulation—governed by stiffness (`k`) and damping (`b`)—remains perfectly deterministic. The UI moves exactly as intended, every single time, everywhere.

UI Engineering as Forensics

Building high-fidelity UI requires fighting decades of browser cruft. Martian UI’s `docs/` folder acts as a living textbook of this battle. It details the undocumented quirks that separate a good interface from a great one: how Chrome and Safari round `scrollTop` differently, or why pointer events silently fail on certain Android devices.

This repository frames UI excellence as an act of archeology. It’s not just about writing clean TypeScript; it’s about understanding the deep, often contradictory behaviors of the underlying rendering engines.

The Anti-Abstraction Mandate

The modern component library ecosystem—tools like shadcn/ui or Mantine—prioritizes developer velocity. They wrap complex behaviors in opaque, batteries-included abstractions. Martian UI takes the exact opposite approach.

Two mechanical devices side by side. On the left, a sleek, sealed black box with a single red button. On the right, an identical machine but the casing is entirely made of clear glass, exposing a complex arrangement of spinning gears, springs, and raw velocity transfer mechanisms.
Martian UI rejects the 'black box' abstraction of modern component libraries in favor of exposed, raw physics variables.

In Martian UI, abstractions that hide physics are considered harmful. The library actively exposes raw variables like velocity (`v`). If you want to build complex, interruptible gestures where one animation seamlessly feeds into another, you cannot have the physics engine hidden behind a black box. You need access to the raw math.

FeatureDeclarative Paradigm (e.g., Mantine)Continuous Paradigm (Martian UI)
State HandlingImmutable, discrete state updatesMutable, continuous state simulation
Event ProcessingInline callbacks (onClick)Buffered, frame-based scheduler
AnimationOpaque CSS/JS wrappersExposed raw velocity vectors (v)
Target AudienceProduct engineers optimizing for speedUI engineers optimizing for absolute fidelity