Get Started

Introduction

An accessible component library for any project. Keyboard navigation, ARIA support, and focus management in 2.2kB of vanilla JavaScript. Backed by 350 automated tests.

The Problem

Building accessible interactive components is hard. They need the right ARIA attributes, keyboard navigation, focus management, and screen reader support. Each component has its own patterns to implement correctly. Getting this right takes time and expertise.

Libraries like Base UI and React Aria solve this beautifully. They handle all the complexity so you don't have to, with great developer experience. The tradeoff is runtime: they require a specific framework loaded on the client to manage state and render updates.

Not every project needs a client-side framework. Static sites, server-rendered pages, content-heavy applications. Sometimes you just want the HTML you wrote to become interactive. Load a script, and it works. And that's exactly what monochrome does.

The Solution

A page with a thousand interactive elements performs exactly the same as a page with one. This isn't an optimization, it's the architecture. Monochrome shares a minimal set of event listeners across every component, with no instances and no per-component overhead.

This also means components are inherently dynamic. Anything added to the page works the moment it appears in the DOM because the library responds to interactions as they happen, not to components registered at startup. Nothing to initialize, nothing to clean up.

The button below is a live monochrome component. No framework initialized it. No query selector found it. Click it and the DOM updates itself.

Components

Four interactive UI patterns:

ComponentPurpose
AccordionGrouped collapsible content sections
CollapsibleShow and hide content with a button
MenuDropdown menus, menubars, and submenus
TabsSwitch between multiple content panels

Frequently Asked Questions

A Personal Note

Monochrome has been my side project for a long time. It's been rebuilt from scratch multiple times, not because it was broken, but because I kept finding a better way. Each version did more with less, until I arrived at an architecture that finally did everything I set out to build.

I've spent a lot of time on the details. Testing every interaction by hand and backing them with automated tests. Optimizing every single byte to arrive at the most efficient solution I could find. This project means a lot to me, and I'd love to hear what you think about it.

Next Steps