Oat UI: The Browser Is the Framework

Kailash Nadh's zero-dependency library styles semantic HTML directly, then reaches for tiny Web Components only where the browser still needs help.

9 min read • View on GitHub • More from knadh

A wide browser window sits at the center while raw semantic controls enter from one side and polished UI emerges from the other. It explains Oat UI's core idea: the browser and CSS do most of the work, while JavaScript stays small.
Oat UI treats the browser as the main rendering engine, not a passive target for a framework.

I wrote this to use in my own projects after getting sick of the ridiculous bloat, dependencies, and rug-pulls in Javascript UI/component libraries.

Kailash Nadh, Author · knadh/oat README
Key Takeaways

Most UI libraries start by asking how to package components. Oat starts by asking how much of the job the browser already knows how to do. That shift matters because it changes the abstraction: the center of gravity moves from framework code back to semantic HTML, modern CSS, and a few narrow JavaScript escape hatches.

The browser does the first draft

A cluttered desk of frontend stacks gets pushed aside by a simple HTML page on a clean surface. It visualizes the author's frustration with bloated UI libraries and the case for restraint.
Oat UI begins as a reaction against frontend excess, not as a new component empire.

Why Kailash Nadh built Oat

WSJ-style hedcut portrait of Kailash Nadh based on his verified GitHub avatar. It introduces the author behind the project before the quote that explains why he built it.

That sentence sets the ceiling. Oat is not trying to be a universal abstraction or a retrofit for a legacy app. It is a deliberate refusal to make every button, modal, and toggle depend on a larger frontend ritual than the browser itself.

Semantic HTML as an API

Oat's most interesting move is simple: it styles native elements directly. A button is still a button, an input is still an input, and the stylesheet meets them there instead of asking you to memorize a private class taxonomy. The CSS leans on modern primitives like @layer, light-dark(), color-mix(), and low-specificity selectors so the cascade becomes part of the design system instead of a source of fights.

A single button is shown as stacked translucent layers and a tiny state hinge. It illustrates how Oat uses layered CSS rather than a big component runtime.
The CSS is layered, but the HTML stays ordinary.

Oat's stack keeps the browser in charge, with JavaScript used only where native HTML and CSS stop short.

Where JavaScript still matters

Oat is not pretending CSS can do everything. Tabs, dropdowns, tooltips, and toast notifications are the places where it reaches for tiny Web Components and a small imperative API. The point is discipline, not purity: state changes are handled where they belong, and the DOM stays readable enough that you can still reason about the page without reverse-engineering a framework runtime.

A tangled pile of component boxes on one side contrasts with a clean semantic page and a tiny adjustment tool on the other. It shows the difference between framework-heavy UI and Oat's browser-first approach.
Oat keeps the interactive surface narrow so the rest of the page can stay plain HTML.

How Oat compares to the minimalist CSS crowd

LibraryCore ideaJavaScriptBest fit
Oat UISemantic HTML first, with browser-native styling and a few Web ComponentsYes, but only for interactive edgesNew projects that want a calm default UI without a framework stack
Water.cssClassless CSS for making simple pages look goodNoneFast docs, small sites, and plain content pages
MVP.cssMinimal classless styling for quick prototypesNonePrototypes and lightweight HTML apps
Pico.cssSemantic, class-light CSS with polished defaultsNoneContent sites and simple app interfaces

The tradeoff: opinionated and intentionally narrow

Oat's strength is also its boundary. It is opinionated, sub-v1, and happiest when you are starting fresh instead of trying to reskin an existing codebase. That makes it less of a universal toolkit and more of a clear bet: if you want a coherent UI with zero runtime baggage, let the browser carry more of the load and keep the rest of the stack small.