A minimal, themeable CSS component library.
Write plain HTML and get styled components automatically, or use classes when you need more control.
npm install mdst-ui
Try a theme
These are stock components, and each theme only changes a handful of CSS variables.
Welcome back
| Name | Role | Status |
|---|---|---|
| AK Ada King | Owner | Online |
| LT Linus T. | Engineer | Away |
| GH Grace H. | Engineer | Online |
| MH Margaret H. | Design | Locked |
Notifications
Pro
Popular- Unlimited projects
- Custom domains
- Priority support
Deploying main
Feedback
It’s mostly HTML
Write normal HTML, and add a class when you want a variant.
<body class="mdst-ui">
<form>
<label for="name">Name</label>
<input id="name" placeholder="Ada">
<select>
<option>Designer</option>
<option>Engineer</option>
</select>
<label>
<input type="checkbox"> Subscribe
</label>
<button>Save</button>
</form>
</body>
<button class="mdst-button--solid">
Publish
</button>
<button class="mdst-button--borderless">
Cancel
</button>
<span class="mdst-tag mdst-tag--success">
Live
</span>
<table class="mdst-table--striped">
…
</table>
| Plan | Seats |
|---|---|
| Starter | 3 |
| Pro | 10 |
| Team | 50 |
<div class="mdst-stepper">
<div class="mdst-stepper__step"
data-state="completed">…</div>
<div class="mdst-stepper__step"
data-state="active">…</div>
<div class="mdst-stepper__step"
data-state="upcoming">…</div>
</div>
<script>
// Bring any JS (or none).
// We style every state.
step.dataset.state = "completed";
</script>
The buttons only flip data-state. All the visual states come from the CSS.
Make a page
Add some blocks, pick a theme, and copy the HTML.
Add a block
Your page
Using it with AI
If an AI is writing your front end, give it something small and predictable to build on.
Native HTML, nothing to invent
No bespoke component API to hallucinate. Models already write good semantic HTML, and modest-ui styles it.
The whole library in one file
llms.txt lists every class, token, and pattern. Drop it into context and your agent knows the system.
Customise with tokens, not rewrites
Brand changes are a handful of --mdst-* variables, so new screens keep matching instead of drifting.
Your CSS always wins
Everything sits in a cascade layer, so any CSS you or your agent add on top wins. No !important wars.
Scoped to .mdst-ui
Adopt it one screen at a time. Third-party widgets and legacy pages outside the scope stay untouched.
Open source, no lock-in
MIT licensed, plain CSS, no build step, and no runtime. Install from npm, use the CDN, or vendor the files.
Use modest-ui (npm: mdst-ui) as the CSS foundation for this project. - Load it: <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/mdst-ui@2/dist/modest-ui.min.css"> or: npm install mdst-ui, then @import "mdst-ui/dist/modest-ui.css"; - Put class="mdst-ui" on <body> and write semantic, native HTML first. - Only add .mdst-* modifier classes for variants (e.g. .mdst-button--borderless). - Drive runtime state with data-state; use modifier classes for variants. - Theme by overriding --mdst-* tokens in :root. Don't restyle components. - Put custom layout CSS in your own layer on top. - Reference: https://modest-ui.com/llms.txt
Example pages
Complete pages built with modest-ui and a little layout CSS.
Landing page
Hero, feature grid, testimonials, and a call to action.
Dashboard
Stat cards, a data table, and action controls.
Pricing
Plan comparison, billing toggle, and FAQ.
Authentication
Login, registration, and password reset forms.
Blog
Article list, tags, and a full reading view.
Settings
Profile editing, notification preferences, and a danger zone.
Install
Add the stylesheet, put .mdst-ui on the body, and write HTML.
npm install mdst-ui
/* in your CSS */ @import "mdst-ui/dist/modest-ui.css"; /* or in your JS bundler */ import "mdst-ui";
<!doctype html> <html lang="en"> <head> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/mdst-ui@2/dist/modest-ui.min.css" /> </head> <body class="mdst-ui"> <h1>Hello world</h1> <button>Click me</button> </body> </html>
/* Always include tokens first */ @import "mdst-ui/base/tokens.css"; /* Then only what you need */ @import "mdst-ui/components/button/button.css"; @import "mdst-ui/components/input/input.css";
How it works
Classless, classes, and your CSS on top
Classless. Bare elements inside .mdst-ui get a styled baseline for free: every native
<button>, <input>, and <table>.
Classes. Component classes like .mdst-button always override the classless defaults, and
modifiers like .mdst-button--borderless work directly on bare elements.
Your CSS. All of modest-ui sits in the mdst-ui cascade layer, so anything you write outside a
layer wins, whatever its specificity or load order.
Scoped and safe
Unlike classless frameworks that style every element on the page globally, modest-ui is scoped to .mdst-ui.
Third-party widgets, embedded content, and anything outside the scope are unaffected. And because it all sits in a cascade
layer, your own styles always take priority.
Theming with tokens
Override CSS custom properties to make it yours. Try the Theme Playground to generate them.
:root {
--mdst-color-fg: #000;
--mdst-color-bg: #fff;
--mdst-color-border: #000;
--mdst-color-muted: #666;
--mdst-color-subtle: #f5f5f5;
--mdst-color-focus: #000;
--mdst-radius: 0;
}
Open source
MIT licensed, so use it, fork it, or send a pull request.