Tool Directory / CSS and UI

Style your app without inheriting a design system

The styling layer is where teams accumulate the most regret, usually by adopting a component library whose visual opinions they spend the next two years fighting. Modern CSS has closed most of the gaps that justified heavy tooling, so the honest options list is shorter than it used to be.

Reviewed August 2026. Back to the tool directory.

What this layer decides

Two separate choices get conflated constantly. The first is how you write styles - utility classes, scoped modules, or plain stylesheets. The second is where your components come from - a dependency you install, source code you own, or your own hands.

Also worth knowing: CSS itself absorbed a lot of what preprocessors existed for. Native nesting, custom properties, container queries, and the :has() selector all ship in every current browser. Sass is no longer load-bearing for most projects, and a small site may need no build step for CSS at all.

How you write the styles

Tailwind CSS

v4 - the Oxide engine era

Version 4 replaced the JavaScript config with CSS-first configuration through the @theme directive and rebuilt the engine in Rust, making incremental builds effectively instant. Utility classes keep styles next to the markup they affect and delete the naming problem entirely. The cost is verbose class attributes and a real learning curve on the spacing and color scales. tailwindcss.com

CSS Modules

Scoped, boring, built into every bundler

Write ordinary CSS in a .module.css file and the bundler hashes the class names so they cannot collide. No runtime, no new syntax, no vendor to depend on, and every developer you hire already knows how to read it. It is the least exciting entry here and the one least likely to need replacing in three years. vite.dev

Vanilla CSS

Genuinely viable again

Custom properties for tokens, native nesting for structure, container queries for component-level responsiveness, cascade layers for specificity control. For a marketing site, a blog, or a documentation site, one hand-written stylesheet under 20KB will beat any framework on load time and never needs an upgrade guide. MDN CSS reference

Runtime CSS-in-JS libraries that inject styles during render - the styled-components generation - are the clear losers of the server-rendering era. They fight React Server Components, add runtime cost, and most have stopped receiving meaningful development. Do not start a new project on one.

Where the components come from

shadcn/ui

Copy the source, own the code

Not a dependency: the CLI copies component source into your repository, where you edit it like any other file. That single design decision solved the oldest problem in component libraries - needing a variant the author did not anticipate. Tailwind v4 and React 19 are fully supported, and 2026 brought a v4 CLI plus registry support for both Radix and Base UI primitives. ui.shadcn.com

Radix Primitives

Behavior without opinions

Unstyled, accessible implementations of the components that are genuinely hard to build correctly: dialogs with focus trapping, comboboxes with the right keyboard model, tooltips that respect pointer intent. Ships zero visual styling, which is exactly why it powers shadcn/ui. The packages were unified into a single install in early 2026. radix-ui.com

Base UI

The newer headless option

Headless primitives from the MUI team, built by people who have maintained accessible components at scale for a decade. It became a supported target in the shadcn registry during 2026, so you can pick between it and Radix without rewriting your components. Younger than Radix; check that the specific primitive you need has landed. base-ui.com

Our pick

Tailwind v4 plus shadcn/ui for apps, plain CSS for content

For an application, run Tailwind v4 with shadcn/ui components copied into your repository. You get a consistent token system, components that are already accessible, and full ownership of the source when you need a variant nobody anticipated. Nothing in that combination can be deprecated out from under you, because the components are your files.

For a content site, write plain CSS. A blog or documentation site does not need a utility engine, a component library, or a build step for its stylesheet, and one file of modern CSS with custom properties will outlive every framework release cycle. CSS Modules is the right middle ground for a team that wants scoping without utility classes.

Keep going

Component libraries are worth testing visually as well as functionally - the testing layer covers Storybook and visual regression, and the static site stack shows what a no-build CSS setup looks like end to end.