Runtime Management
This section covers how to manage and control the runtime behavior of Twigwind's JavaScript engine.
ES6 Module Setup
Twigwind now uses ES6 modules for modern JavaScript environments:
<script src="src/css.js" type="module"></script>
Basic Runtime Initialization
The standard way to initialize Twigwind is to process all elements with classes and inject the generated CSS:
document.addEventListener("DOMContentLoaded", () => {
document.querySelectorAll("[class]").forEach(el => Twigwind.twApply(el));
Twigwind.twInject();
});
Build-Time Alternative
For production optimization, use the build system instead of runtime generation:
node build.js
This generates optimized CSS files in the dist/ directory containing only the utilities you actually use.
Core Functions
Twigwind exposes several key functions for runtime management:
twApply(element)
Processes all classes on a specific element and generates corresponding CSS rules.
const myElement = document.getElementById("my-element");
Twigwind.twApply(myElement);
twInject()
Injects all generated CSS rules into the document head as a <style> element.
Twigwind.twInject();
Dynamic Class Updates
When you dynamically add or change classes, you need to reprocess the element and inject new styles:
Example: Dynamic Color Change
const button = document.getElementById("my-button");
button.addEventListener("click", () => {
// Toggle between blue and red background
if (button.classList.contains("bg-blue")) {
button.classList.remove("bg-blue");
button.classList.add("bg-red");
} else {
button.classList.remove("bg-red");
button.classList.add("bg-blue");
}
// Reprocess the element and inject new CSS
Twigwind.twApply(button);
Twigwind.twInject();
});
Example: Adding Animation
const card = document.querySelector(".card");
card.addEventListener("mouseenter", () => {
card.classList.add("animate-bounce-500ms-normal");
Twigwind.twApply(card);
Twigwind.twInject();
});
card.addEventListener("mouseleave", () => {
card.classList.remove("animate-bounce-500ms-normal");
// No need to reprocess since we're removing classes
});
Performance Optimization
For better performance when making multiple changes:
Batch Processing
// Instead of calling twInject() multiple times
const elements = document.querySelectorAll(".dynamic-element");
elements.forEach(el => {
el.classList.add("new-class");
Twigwind.twApply(el);
});
// Inject once at the end
Twigwind.twInject();
twInject() frequently. Batch your class changes and inject once when possible.
Available Utility Functions
Twigwind exposes individual utility functions for specific use cases:
twColor(className)- Process color utilities (bg-, color-)twSpacing(className)- Process spacing utilities (p-, m-)twSize(className)- Process size utilities (w-, h-, size-)twflex(className)- Process flex utilitiestwGrid(className)- Process grid utilitiestwPosition(className)- Process position utilitiestwAnimation(className)- Process animation utilitiestwLinearGradient(className)- Process gradient utilitiestwImage(className)- Process image utilities
Using Individual Functions
// Process only specific utility types
Twigwind.twColor("bg-blue");
Twigwind.twSpacing("p-20");
Twigwind.twAnimation("animate-spin-1s-infinite");
Twigwind.twInject();
Real-World Examples
Theme Switcher
function switchTheme(isDark) {
const elements = document.querySelectorAll("[data-theme]");
elements.forEach(el => {
if (isDark) {
el.classList.remove("bg-white", "color-black");
el.classList.add("bg-black", "color-white");
} else {
el.classList.remove("bg-black", "color-white");
el.classList.add("bg-white", "color-black");
}
Twigwind.twApply(el);
});
Twigwind.twInject();
}
Progressive Enhancement
// Add classes progressively as user scrolls
window.addEventListener("scroll", () => {
const cards = document.querySelectorAll(".scroll-card");
cards.forEach((card, index) => {
const rect = card.getBoundingClientRect();
if (rect.top < window.innerHeight) {
card.classList.add(`animate-fadeIn-${(index + 1) * 200}ms-normal`);
Twigwind.twApply(card);
}
});
Twigwind.twInject();
});