Getting started
iVOLT ships as prebuilt CSS and JavaScript. Two files are enough: a stylesheet and a module. No build step, no configuration file, no runtime dependency — and the same two files work in plain HTML, WordPress, Astro or any bundler.
<div class="iv-cluster">
<button class="iv-button iv-button--primary" type="button">Primary</button>
<button class="iv-button iv-button--secondary" type="button">Secondary</button>
<button class="iv-button iv-button--ghost" type="button">Ghost</button>
<button class="iv-button iv-button--danger" type="button">Danger</button>
<button class="iv-button" type="button">Neutral</button>
<a class="iv-button iv-button--secondary" href="#docs">Link as button</a>
</div>Install from npm
One command, no peer dependencies to resolve.
npm install @intervolutions/ivoltPin the exact version in production. From 1.0 the package follows SemVer: what is public, and how it is allowed to change, is written down in stability.
Build the package
From a checkout, the same files the registry serves.
git clone https://github.com/iNTERVOLUTIONS-Labs/iVOLT
cd iVOLT
npm ci
npm run build # writes packages/ivolt/distPlain HTML, no Node
Copy packages/ivolt/dist next to your page and link the files.
Add the iv-root class where base typography should apply; on <html> for a whole page, or on a wrapper when embedding into an existing site.
<!DOCTYPE html>
<html lang="en" class="iv-root" data-iv-theme="system">
<head>
<link rel="stylesheet" href="ivolt/css/ivolt.min.css">
<script type="module" src="ivolt/js/auto.js"></script>
</head>Prefer a classic script? ivolt/js/ivolt.iife.min.js exposes one global, IVOLT, and does not initialise anything until you call IVOLT.init().
ES modules with a bundler
The package exports are the public API; deep paths into dist/ are not.
import "@intervolutions/ivolt/css/ivolt.css";
import { init, Dialog } from "@intervolutions/ivolt";
import { setTheme } from "@intervolutions/ivolt/theme";
init(document); // explicit, idempotent
const dialog = Dialog.get(document.querySelector("#signup"));Importing @intervolutions/ivolt has no side effects; only @intervolutions/ivolt/auto initialises on load. Modules never touch document at import time, so they are safe in server-side rendering.
Pick the CSS you need
| File | Contains |
|---|---|
css/ivolt.css | Everything, organised in cascade layers iv.reset, iv.tokens, iv.base, iv.layout, iv.components, iv.utilities, iv.overrides. |
css/ivolt.flat.css | Same rules without @layer, for sites whose existing CSS is not layered and must keep competing by specificity. |
css/core.css | Tokens, base and layout only. |
css/components/*.css | One file per component, unlayered. Import after core.css; assign a layer yourself if you use them: @import url("…/components/button.css") layer(iv.components); |
css/reset.css | Optional normalisation. It is unlayered: import it with @import url("…/reset.css") layer(iv.reset), or link css/reset.layer.css, which is already wrapped. |
Both sheets are on the stage above: the flat sheet control swaps the layered stylesheet for the unlayered one on a page that is already running.
Coexisting with existing CSS
Cascade layers order iVOLT's own rules; they do not isolate it. Any normal (non-!important) rule outside a layer beats every layered rule, whatever its specificity. A theme rule like button { background: red } therefore overrides .iv-button in ivolt.css. Two ways out: use ivolt.flat.css, or wrap the legacy stylesheet in a layer declared before iVOLT's: @import url("theme.css") layer(legacy);. Base element styles only apply inside .iv-root, so headings, links and inputs outside it are left alone.
Browser support
Designed for Chrome and Edge 111+, Firefox 113+, Safari and iOS 16.4+, Samsung Internet 22+. The build targets these versions; container queries and popover are progressive enhancements. No Internet Explorer. Automated tests run in Chromium, Firefox and WebKit through Playwright, which is not the same as testing every physical device.