Lifecycle
The engine has three phases: load, first scan, and observation. This page walks through each.
1. Load
When chai.js is parsed, the UMD wrapper:
- Reads the default theme.
- Defines the rules array.
- Reads
data-chai-*attributes fromdocument.currentScript. - Reads
meta[name="chai-config"](JSON). - Constructs
window.chai = new Chai(config). - If
autoStart !== false, callschai.start().
If autoStart is false, nothing happens until you call it yourself.
2. First scan
chai.start() schedules chai.scan(document.body) for DOMContentLoaded (or runs it immediately if the document is already past loading). The scan:
- Walks every descendant of
<body>viaquerySelectorAll('*'). - For each element, calls
chai.apply(el). applyreadsel.classList, parses everychai-*class, merges the resulting style objects, and writes them viastyle.setProperty(...).- Unless
keepClassesis true, the matched classes are removed.
This runs once per start() call. The scan returns the number of classes successfully applied.
3. Observation
After the first scan, if observe is true, a MutationObserver is attached to document.body watching:
childList(subtree: true) — for anyaddedNodes, the engine callsscan(node)so newly inserted DOM is styled.attributes(filter:class) — for any element whoseclassattribute changes, the engine callsapply(el).
A _mutating flag is flipped during the engine’s own writes so its own class-removal doesn’t trigger an infinite loop.
Stopping
chai.stop() disconnects the observer. Already-applied inline styles remain on the elements. New nodes added after stop() won’t be styled until you start() again or call scan(node) manually.
Manual control
You can run chaiTailwind in fully-manual mode by disabling auto-start and observation:
<script src="chai.js" data-chai-auto-start="false" data-chai-observe="false"></script><script> // …construct or append your DOM… window.chai.scan(document.body); // explicit, one-shot pass</script>Or programmatically:
import { Chai } from 'chaitailwind';
const chai = new Chai({ autoStart: false, observe: false });// later, after your framework has rendered:chai.scan(document.getElementById('root'));Hot-reloading the engine
If you change the theme at runtime, re-scan to apply the new values:
chai.theme.colors.brand = '#ff0000';chai.scan(); // re-resolves chai-bg-brand etc.(Re-scanning is idempotent and overwrites inline styles.)
Made by Saad · @developedbysaad on X