Keystone gives you styles, icons, and behavior as three independent layers — each a single include that works from a CDN or a local file, on its own or together.
Small, honest, and dependency-free. Use exactly the parts you want.
Want our icons but not our styles? Our JS but your own CSS? Every pillar stands alone and degrades gracefully when the others are absent.
No frameworks, no runtime, no bundler. The behavior layer is vanilla JavaScript written from scratch. Drop the files in and go.
The same single tag works whether you link to a CDN or download the files. Icons embed their font, so there's no assets folder to chase.
Everything is built on --ks-* CSS custom properties. Retheme by overriding variables; dark mode ships in the box.
Focus management, ARIA wiring, keyboard support, and reduced-motion respect are built into the components — not bolted on.
Add your own components with a buildless plugin system: drop a module, list it in config.json, and it loads at runtime.
Each is one include. Use one, two, or all three.
Design tokens and component classes — buttons, forms, cards, modals, tabs, tables and more.
<link rel="stylesheet" href="keystone.css">
601 geometric icons in one self-contained file — the webfont is base64-embedded, so there's nothing else to download.
<link rel="stylesheet" href="keystone-icons.css">
From-scratch components: modals, drawers, dropdowns, tabs, accordions, tooltips, toasts, theme & form helpers.
<script type="module" src="keystone.js"></script>
Link to it, or download it. Then write plain HTML.
Drop these in your <head>. Keep only the pillars you need.
<link rel="stylesheet" href="https://ui.aheliotech.app/keystone.css"> <link rel="stylesheet" href="https://ui.aheliotech.app/keystone-icons.css"> <script type="module" src="https://ui.aheliotech.app/keystone.js"></script>
Served from ui.aheliotech.app. Pin a version when releases are tagged.
<link rel="stylesheet" href="keystone.css"> <link rel="stylesheet" href="keystone-icons.css"> <script type="module" src="keystone.js"></script>
Download the files below and reference them from your project.
Components are plain classes and data-ks-* hooks. The behavior layer wires them up automatically.
<body class="ks-body ks-scope">
<button class="ks-btn ks-btn--primary" data-ks-modal-open="hello">
<span class="ks-i ks-i-controls-search"></span> Open
</button>
<div class="ks-modal" data-ks-modal id="hello">
<div class="ks-modal-dialog">
<div class="ks-modal-header">
<h3 class="ks-modal-title">Hello</h3>
<button class="ks-modal-close" data-ks-modal-close></button>
</div>
<div class="ks-modal-body">It works.</div>
</div>
</div>
</body>
These controls are live — rendered by the same Keystone files this page loads.
This dialog is rendered by keystone.js — focus is trapped, Esc closes it, and the backdrop dismisses on click.
It works.
Grab individual files, or take the whole keystone/ folder.
No build, no bundler. Drop a module, list it, and it loads at runtime.
plugins/config.json
[
{ "path": "sample/main.js", "enabled": true },
{ "path": "my-plugin/main.js" }
]
plugins/my-plugin/main.js
export default function register(ks) {
ks.register('greeter', {
selector: '[data-greet]',
mount(el) {
ks.utils.on(el, 'click', () =>
ks.toast({ message: 'Hi!' }));
},
});
}
The core fetches config.json relative to keystone.js and imports each module in the order you list. A missing config is harmless.
No pillar requires another. Load whatever fits.
| Loaded | Result |
|---|---|
| Icons only | .ks-i-* glyphs render. |
| Style only | Components fully styled; interactive ones sit in their default state. |
| Behavior only | Behaviors work; injected marks are inline SVG; appearance is unstyled. |
| Any combination | Progressive enhancement, with no errors when a pillar is absent. |
A two-tone bracketed [KS] — technical and corporate. Download the assets below.