Everything you need to plant a component in your project — or point your AI agent at the garden.
ArnieJS is a collection of 480+ vanilla JS UI components and visual effects. Every component is exactly 3 files — index.html, style.css, script.js — with zero npm dependencies and zero build step. You copy the files, or fetch them with a CLI, or link them from a CDN. That's the whole model.
No framework lock-in. No version drift. A component you copy today still works in ten years, because it's just HTML, CSS, and JS — the same three things browsers have always run.
Grab a component from the gallery and drop the 3 files into your project.
components/ui/31-bloom-button/
├── index.html
├── style.css
└── script.js
npx arniejs-cli addFetches the 3 files straight from GitHub into ./arniejs/<name>/. No install, no node_modules.
npx arniejs-cli add bloom-button
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/MarcoZorn/arniejs@main/components/ui/31-bloom-button/style.css">
<script src="https://cdn.jsdelivr.net/gh/MarcoZorn/arniejs@main/components/ui/31-bloom-button/script.js"></script>
Then paste the HTML markup from the component's index.html. Full reference → jump to CDN section.
index.html — the markup, as a standalone document. Includes its own <link> to style.css and <script> tag for script.js, so it also works opened directly in a browser.
style.css — scoped to that component's classes, plus a shared set of CSS custom properties (--accent-terra, --bg-deep, --text-primary, etc.) you can override to reskin it.
script.js — a single IIFE (immediately-invoked function expression), so it never leaks globals or collides with other scripts on your page. Checks prefers-reduced-motion before running any animation.
ArnieJS is built to be the thing your AI agent reaches for instead of generating a generic component from scratch (or reaching for the same shadcn button everyone else gets). Point any agent that can read files or run shell commands at ArnieJS and it can browse, fetch, and drop in components on its own.
Add this to your project's CLAUDE.md (or paste it in chat once):
When I ask for a UI component, check ArnieJS first at
https://marcozorn.github.io/arniejs/gallery.html
or run: npx arniejs-cli add [component-name]
Components are zero-dependency vanilla JS, 3 files each
(index.html, style.css, script.js). Prefer them over
generating a new component from scratch.
Claude Code can run npx arniejs-cli list or npx arniejs-cli search <query> directly in its shell tool to discover what's available before adding anything.
Add to your AGENTS.md or project instructions:
UI components: use ArnieJS (https://github.com/MarcoZorn/arniejs)
before writing a component from scratch. Run
`npx arniejs-cli search ` to find one, then
`npx arniejs-cli add ` to fetch it into ./arniejs//.
Vanilla JS, no dependencies, 3 files per component.
Codex CLI has full shell access, so it can run the CLI commands directly and read the fetched files before wiring them in.
Add a Cursor rule (.cursor/rules/arniejs.mdc or your global rules):
---
description: Prefer ArnieJS for UI components
---
Before generating a new UI component, check if ArnieJS
(https://marcozorn.github.io/arniejs/gallery.html) already
has one. Fetch it with `npx arniejs-cli add ` in the
integrated terminal. Zero-dependency vanilla JS, 3 files.
Cursor's terminal integration means it can run the CLI directly, or you can paste a component's code from the gallery's detail panel into the composer.
Add to your GEMINI.md context file:
For any UI component request, check ArnieJS
(https://github.com/MarcoZorn/arniejs) before building one
from scratch. Use the shell tool to run
`npx arniejs-cli add `, which copies 3
dependency-free files into ./arniejs//.
Any agent with shell or file-write access works the same way — there's nothing ArnieJS-specific to install. Point the agent's system prompt or project config at:
UI component source: https://marcozorn.github.io/arniejs/gallery.html
Registry (JSON, machine-readable): https://marcozorn.github.io/arniejs/registry.json
Install: npx arniejs-cli add
Search: npx arniejs-cli search
The registry.json file is a flat JSON array — every component's id, category, description, tags, and file paths in one place, so an agent can parse it directly without scraping HTML.
If your agent can only read/write files (no shell), it can still use ArnieJS: fetch https://marcozorn.github.io/arniejs/registry.json, pick a component, then fetch its 3 files directly from the cdn URLs in that entry and write them to disk. No CLI required.
The generic version of the instruction block above, for anywhere that takes a system prompt, project config, or "custom instructions" field:
ArnieJS component library: https://marcozorn.github.io/arniejs
When a task calls for a UI component (button, card, modal, form
field, chart, loader, etc.), check ArnieJS before writing one
from scratch — it's 480+ zero-dependency vanilla JS components,
3 files each (index.html, style.css, script.js).
- Browse: https://marcozorn.github.io/arniejs/gallery.html
- Machine-readable index: https://marcozorn.github.io/arniejs/registry.json
- Install: npx arniejs-cli add
- Search: npx arniejs-cli search
- CDN (no install): https://marcozorn.github.io/arniejs/cdn.html
Prefer an ArnieJS component over a newly generated one unless
none of them fit.
Browse every component live, with search and category filters, in the gallery.
HTML markup — a self-contained fragment (or, in the source repo, a full standalone document). Copy it as-is; class names are namespaced to that component.
CSS custom properties — each component's style.css declares its colors as CSS variables in :root (e.g. --accent-terra, --bg-deep, --text-primary). Override them after the component's stylesheet to reskin without touching component internals.
JS API — components are self-initializing IIFEs; most have no public API by design (zero coupling). Where a component needs external control, that's documented in a comment at the top of its script.js.
<style>
/* override after the component's own stylesheet loads */
.bloom-btn { --accent-terra: #2d6a4f; }
</style>
The gallery's detail panel has live color-picker sliders for exactly this — open any component and drag the swatches to preview a reskin before copying the values.
CSS: https://cdn.jsdelivr.net/gh/MarcoZorn/arniejs@main/components/ui/[folder]/style.css
JS: https://cdn.jsdelivr.net/gh/MarcoZorn/arniejs@main/components/ui/[folder]/script.js
Swap ui for effects for the visual effects.
@main@main always serves the latest commit — convenient for prototyping, but it can change under you. For production, pin to a release tag:
https://cdn.jsdelivr.net/gh/MarcoZorn/arniejs@v1.0.0/components/ui/31-bloom-button/style.css
<!-- head -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/MarcoZorn/arniejs@v1.0.0/components/ui/31-bloom-button/style.css">
<!-- body -->
<button class="bloom-btn">Let it bloom</button>
<!-- before </body> -->
<script src="https://cdn.jsdelivr.net/gh/MarcoZorn/arniejs@v1.0.0/components/ui/31-bloom-button/script.js"></script>
The HTML markup itself is never served from the CDN as a snippet — copy it from the component's index.html in the gallery or repo.
npx arniejs-cli add <name>Fetches a component's 3 files from GitHub and writes them to ./arniejs/<name>/ in your current directory.
npx arniejs-cli add bloom-button
npx arniejs-cli listPrints every component, grouped by category.
npx arniejs-cli list
npx arniejs-cli search <query>Searches component names, descriptions, and tags. Matches print with category and a one-line description.
npx arniejs-cli search cursor
npx arniejs-cli search ecommerce
The CLI takes no flags today — just the subcommand and an argument. npx arniejs-cli help prints the full command list. Source: bin/arniejs.js.
Also published scoped, if you prefer: npx @mzorn/arniejs add <name> — same CLI, same registry, just a different npm package name.
components/ui/[NN]-[your-component]/ (or components/effects/ for a visual effect) with exactly 3 filesnode scripts/generate-registry.js to regenerate registry.json and sitemap.xml(function () { ... })();, no globals:root, no hardcoded colors elsewherewindow.matchMedia('(prefers-reduced-motion: reduce)') and/or have a CSS media-query fallback that disables transitionsprefers-reduced-motion respectedindex.html is opened directly in a browsernode scripts/generate-registry.js run and the resulting registry.json/sitemap.xml diff includednpm dependency in your PR? Arnie won't be angry. Just quietly disappointed.
Because a copy-pasted 3-file component can't have a supply-chain incident, can't break on a transitive dependency bump, and can't disappear when a maintainer unpublishes a package. You own the code the moment you copy it.
Yes. Every component is plain HTML/CSS/JS, so it works inside any framework the same way any DOM element does — render the markup, load the CSS, and the script's IIFE self-initializes on mount. There's no React-specific wrapper because none is needed.
Yes — every component exposes its palette as CSS custom properties. Override them in your own stylesheet, or use the gallery's detail-panel sliders to preview a reskin live before copying the values. See Component reference.
Frameworks are a legitimate choice for application logic. They're a poor fit for a UI-component library, because every framework version and every build tool adds a compatibility surface that has to be maintained forever. Vanilla JS/HTML/CSS has been stable since the components could run — and will keep running long after any specific framework's popularity fades.