Modern CSS, No Build: How 37signals Ships Complex Apps with Vanilla Styles

37signals built three substantial apps with vanilla CSS and no build tools, relying on modern features like custom properties, nesting, container queries, :has(), and CSS Layers. Their simple, flat architecture with semantic components, OKLCH colors, ch-based spacing, and additive utilities proves maintainable and powerful. The article urges teams to reconsider defaulting to Tailwind or preprocessors and to embrace native CSS where it suffices.
Key Points
- Modern CSS features (custom properties, nesting, container queries, :has(), layers, color-mix(), clamp) remove the need for preprocessors and many build-time tools.
- A flat, file-per-concept architecture plus semantic component classes keeps CSS maintainable while utilities remain additive and minimal.
- An OKLCH-based color system and color-mix() enable robust theming, effortless dark mode, and dynamic palettes without duplication.
- Content-driven layout uses ch units and character-based breakpoints to make responsiveness semantic and typography-aligned.
- :has() and CSS Layers are game-changers—:has() enables declarative stateful styling, and layers resolve specificity without order hacks.
Sentiment
The Hacker News discussion presents a mixed and nuanced sentiment regarding the article's claim that vanilla CSS is all you need. While there's an appreciation for modern CSS capabilities and the principle of avoiding frameworks, many commenters highlight practical difficulties, productivity trade-offs, and the perceived benefits of frameworks or build-time CSS tools for complex projects or non-designers.
In Agreement
- Modern CSS features like `:has()` and native HTML popovers are powerful and eliminate many traditional CSS headaches.
- It is generally best to push HTML, CSS, and JavaScript to their limits and avoid frameworks unless they are absolutely necessary, due to the complexity, fragility, and supply chain risks frameworks introduce.
- Some developers prefer vanilla CSS over frameworks.
- There are legitimate criticisms against utility-first frameworks like Tailwind.
Opposed
- Despite the power of modern CSS, developing UIs with a vanilla-first approach (e.g., using Hotwire with vanilla CSS) can create significant friction, such as concepts spread across multiple files, reliance on 'magic strings,' and lack of compile-time checks, leading to a return to frameworks like React+Tailwind for productivity.
- Tailwind significantly increases developer speed for some users.
- Non-designers find it difficult to create aesthetically pleasing interfaces from scratch using only vanilla CSS, and existing templates are often cumbersome.
- CSS Modules offer valuable features like `composes` for base classes and `import` for namespacing that are not yet natively available in vanilla CSS, indicating a perceived need for build-time enhancements for certain organizational patterns.