Runtime Management

This section covers how to manage and control the runtime behavior of Twigwind's JavaScript engine.

💡 Tip: Twigwind's JavaScript engine dynamically generates CSS based on the classes found in your HTML.

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();
⚠️ Performance Note: Avoid calling twInject() frequently. Batch your class changes and inject once when possible.

Available Utility Functions

Twigwind exposes individual utility functions for specific use cases:

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();
});
✅ Pro Tip: Twigwind's runtime system is designed to be lightweight and efficient, generating only the CSS you actually use!