🌟 A lightweight, pure vanilla JavaScript utility library that makes DOM manipulation and event handling simple and efficient. 🌟
6x smaller than jQuery • Zero dependencies • Modern ES6+ • Performance optimized
<!-- Via jsDelivr CDN -->
<script src="https://cdn.jsdelivr.net/gh/lam0819/MicroUI@latest/dist/microui.min.js"></script>
<!-- Via GitHub Releases -->
<script src="https://github.com/lam0819/MicroUI/releases/latest/download/microui.min.js"></script>Why Vanilla JS? • Performance • Examples • Building • Contributing
- Pure Vanilla JS: Zero dependencies, no frameworks, just native JavaScript
 - Ultra Lightweight: Only 18.2KB minified (5.1KB gzipped) - 6x smaller than jQuery
 - Modern: Built with ES6+ features and Promise-based APIs
 - Fast: Event delegation by default, optimized for performance
 - Complete: Includes DOM manipulation, AJAX, animations, components, and more
 - Simple: Clean, intuitive API that's easy to learn
 - No Build Required: Drop in a script tag and start coding
 
Modern web development has become unnecessarily complex. While frameworks like React, Vue, and Angular are powerful, they often introduce:
- Build Complexity: Webpack, Babel, and countless dependencies
 - Bundle Bloat: Megabytes of JavaScript for simple interactions
 - Learning Overhead: New syntax, concepts, and paradigms
 - Runtime Overhead: Virtual DOM diffing and framework abstractions
 
jQuery revolutionized web development by making DOM manipulation simple and cross-browser compatible. However:
- Outdated: Built for IE6 era, carries legacy baggage
 - Large: 87KB minified, 30KB gzipped - too heavy for modern needs
 - Monolithic: Can't tree-shake unused features
 - Not Modern: No ES6+, Promises, or modern JavaScript features
 
"Maximum functionality, minimum complexity"
MicroUI brings back the simplicity of jQuery while embracing modern JavaScript:
// jQuery way (2006)
$(document).ready(function() {
  $('.button').click(function() {
    $(this).addClass('clicked');
  });
});
// MicroUI way (2024)
MicroUI.ready(() => {
  MicroUI.on('click', '.button', function() {
    MicroUI.addClass(this, 'clicked');
  });
});No frameworks. No dependencies. Just JavaScript.
MicroUI is built entirely with native browser APIs, making it:
- No Virtual DOM: Direct DOM manipulation is faster for most use cases
 - Zero Runtime Overhead: No framework initialization or abstractions
 - Native Speed: Direct access to browser APIs without wrappers
 - Memory Efficient: No framework memory footprint
 
- Familiar API: If you know jQuery, you know MicroUI
 - Modern Features: Promises, async/await, ES6+ syntax
 - TypeScript Ready: Full type definitions included
 - No Build Required: Drop in a script tag and start coding
 
- Web Standards: Built on stable browser APIs
 - Framework Agnostic: Use with React, Vue, or anything
 - Future Proof: Vanilla JavaScript never goes out of style
 - Zero Breaking Changes: Stable API you can depend on
 
| Feature | MicroUI | jQuery | React | Alpine.js | Vanilla JS | 
|---|---|---|---|---|---|
| Bundle Size | 5.1KB gzipped | 30KB gzipped | 42KB+ gzipped | 15KB gzipped | 0KB | 
| Learning Curve | ⭐⭐ Easy | ⭐⭐ Easy | ⭐⭐⭐⭐⭐ Steep | ⭐⭐⭐ Medium | ⭐⭐⭐⭐ Hard | 
| Build Required | ❌ Optional | ❌ No | ✅ Yes | ❌ No | ❌ No | 
| Modern Syntax | ✅ ES6+ | ❌ ES5 | ✅ JSX | ✅ ES6+ | ✅ Native | 
| Component System | ✅ Built-in | ❌ Plugins | ✅ Core | ✅ Directives | ❌ Manual | 
| Event Delegation | ✅ Default | ✅ Manual | ❌ Manual | ✅ Auto | ❌ Manual | 
| Animation API | ✅ Web Animations | ❌ CSS only | ❌ CSS/Libraries | ❌ CSS only | ✅ Native | 
| AJAX Promises | ✅ Native | ❌ Custom | ❌ External | ❌ Fetch | ✅ Native | 
| TypeScript | ✅ Included | ⭐ Community | ✅ First-class | ❌ Limited | ✅ Native | 
- Content Websites: Blogs, marketing sites, documentation
 - E-commerce: Product pages, shopping carts, checkout flows
 - Dashboards: Admin panels, analytics interfaces
 - Progressive Enhancement: Adding interactivity to existing sites
 - Prototyping: Quick experiments and proof of concepts
 - Team Onboarding: Easy for junior developers to understand
 
- Complex SPAs: Applications with heavy state management
 - Real-time Apps: Chat applications, collaborative tools
 - Data-Heavy UIs: Large tables, complex visualizations
 - Team Standardization: If your team is already invested in a framework
 
// Traditional Framework Component
function TodoApp() {
  const [todos, setTodos] = useState([]);
  const [inputValue, setInputValue] = useState('');
  
  const addTodo = useCallback(() => {
    setTodos(prev => [...prev, { id: Date.now(), text: inputValue }]);
    setInputValue('');
  }, [inputValue]);
  
  return (
    <div>
      <input 
        value={inputValue} 
        onChange={e => setInputValue(e.target.value)}
        onKeyPress={e => e.key === 'Enter' && addTodo()}
      />
      <button onClick={addTodo}>Add</button>
      {todos.map(todo => (
        <div key={todo.id}>{todo.text}</div>
      ))}
    </div>
  );
}
// MicroUI Component
MicroUI.component('todo-app', {
  template: `
    <div>
      <input class="todo-input" placeholder="Add todo...">
      <button class="add-btn">Add</button>
      <div class="todos"></div>
    </div>
  `,
  
  events: {
    'click .add-btn': 'addTodo',
    'keypress .todo-input': function(e) {
      if (e.key === 'Enter') this.methods.addTodo();
    }
  },
  
  methods: {
    addTodo() {
      const input = MicroUI.$('.todo-input');
      const text = input.value.trim();
      if (text) {
        MicroUI.append('.todos', `<div>${text}</div>`);
        input.value = '';
      }
    }
  }
});Performance Benefits:
- Faster Initial Load: Smaller bundle = quicker downloads and parsing
 - Lower Memory Usage: No framework overhead, minimal runtime footprint
 - Better Mobile Performance: Less JavaScript to parse and execute
 - Improved Core Web Vitals: Smaller bundles improve Lighthouse scores
 
MicroUI delivers exceptional performance through modern optimization techniques:
# Production Build Sizes (Automated via GitHub Actions)
Original:     ~45KB (source code)
Minified:     18.2KB (60% reduction)
Gzipped:      5.1KB (89% reduction)
# Comparison with Popular Libraries (Gzipped)
jQuery 3.7:   30KB (5.8x larger)
React 18:     13KB (2.5x larger)  
Vue 3:        16KB (3.1x larger)
Alpine.js:    15KB (2.9x larger)- Event Delegation: All events use delegation by default (faster than direct binding)
 - DOM Optimization: Smart caching and batched operations
 - Memory Efficient: Minimal memory footprint with automatic cleanup
 - Native APIs: Direct browser API usage for maximum speed
 - Tree Shakable: Import only the modules you need
 
MicroUI prioritizes performance through:
- Zero Dependencies: No framework overhead or initialization cost
 - Small Bundle Size: 5.1KB gzipped means faster downloads and parsing
 - Native JavaScript: Direct browser API access without abstractions
 - Event Delegation: Efficient event handling for dynamic content
 - Minimal Overhead: Direct DOM manipulation without virtual DOM diffing
 
# Download time on different connections
MicroUI (5.1KB gzipped):
  - Fast 3G: ~50ms
  - Slow 3G: ~165ms
  - 2G: ~665ms
jQuery (30KB gzipped):
  - Fast 3G: ~300ms  
  - Slow 3G: ~1000ms
  - 2G: ~4000ms- User Experience: Faster loading = better user engagement
 - SEO Benefits: Google factors page speed into search rankings
 - Mobile Performance: Critical for slower devices and networks
 - Developer Productivity: Less build time, faster development cycles
 - Hosting Costs: Smaller bundles = less bandwidth = lower costs
 
<!-- Via jsDelivr CDN (Latest) -->
<script src="https://cdn.jsdelivr.net/gh/lam0819/MicroUI@latest/dist/microui.min.js"></script>
<!-- Via jsDelivr CDN (Specific Version) -->
<script src="https://cdn.jsdelivr.net/gh/lam0819/[email protected]/dist/microui.min.js"></script>
<!-- Via unpkg CDN -->
<script src="https://unpkg.com/@extralam/microui@latest/dist/microui.min.js"></script>npm install @extralam/microui// ES6 Import
import MicroUI from '@extralam/microui';
// CommonJS
const MicroUI = require('@extralam/microui');Download the latest release from GitHub Releases
<!-- Local file -->
<script src="microui.min.js"></script><!-- ES Module -->
<script type="module">
  import MicroUI from 'https://unpkg.com/@extralam/microui@latest/dist/microui.esm.js';
  // Your code here
</script><!DOCTYPE html>
<html>
<head>
  <script src="https://cdn.jsdelivr.net/gh/lam0819/MicroUI@latest/dist/microui.min.js"></script>
</head>
<body>
  <button class="my-button">Click me!</button>
  
  <script>
    // DOM ready
    MicroUI.ready(() => {
      // Event handling
      MicroUI.on('click', '.my-button', function() {
        this.textContent = 'Clicked!';
        
        // AJAX request
        MicroUI.get('/api/data')
          .then(data => console.log(data));
      });
    });
  </script>
</body>
</html>MicroUI is built around a few core principles:
- Event Delegation: All events use delegation for better performance
 - Promise-Based: All async operations return Promises
 - Modular: Use only what you need
 - Vanilla JS: No new syntax or compilation required
 
MicroUI.ready(() => {
  console.log('DOM is ready!');
});// Basic event
MicroUI.on('click', '.button', function(e) {
  console.log('Clicked:', this);
});
// Multiple events
MicroUI.on('mouseenter mouseleave', '.hover', function(e) {
  this.classList.toggle('active');
});
// One-time event
MicroUI.once('click', '.one-time', function() {
  console.log('This only fires once');
});
// Remove events
MicroUI.off('click', '.button');// Query elements
const element = MicroUI.$('.my-element');
const elements = MicroUI.$$('.all-elements');
// Manipulate classes
MicroUI.addClass(element, 'active highlight');
MicroUI.removeClass(element, 'inactive');
MicroUI.toggleClass(element, 'visible');
// Insert content
MicroUI.append('.container', '<div>New content</div>');
MicroUI.prepend('.container', '<div>First content</div>');
MicroUI.html('.container', '<p>Replace all content</p>');
// Attributes and data
MicroUI.attr(element, 'id', 'my-id');
MicroUI.data(element, 'user', { name: 'John', age: 30 });// GET request
MicroUI.get('/api/users')
  .then(users => console.log(users))
  .catch(error => console.error(error));
// POST request
MicroUI.post('/api/users', {
  name: 'John Doe',
  email: '[email protected]'
}).then(response => console.log(response));
// Load HTML
MicroUI.load('.content', '/partial.html');// Fade effects
MicroUI.fadeIn('.element', 300);
MicroUI.fadeOut('.element', 300, () => console.log('Fade complete'));
// Slide effects
MicroUI.slideDown('.dropdown', 400);
MicroUI.slideUp('.dropdown', 400);
// Custom animation
MicroUI.animate('.box', {
  transform: ['translateX(0)', 'translateX(100px)'],
  opacity: [1, 0.5]
}, {
  duration: 500,
  easing: 'ease-out'
});Attach an event handler using delegation.
MicroUI.on('click', '.button', function(e) {
  console.log('Clicked:', this);
});Remove event handlers.
MicroUI.off('click', '.button');Attach a handler that fires only once.
MicroUI.once('submit', '.form', function(e) {
  e.preventDefault();
  console.log('Form submitted once');
});Trigger a custom event.
MicroUI.trigger('.element', 'customEvent', { value: 42 });Query single element (with caching).
const header = MicroUI.$('.header');Query multiple elements.
const buttons = MicroUI.$$('.button');Add one or more classes.
MicroUI.addClass(element, 'active highlight');Remove one or more classes.
MicroUI.removeClass(element, 'inactive');Toggle a class.
MicroUI.toggleClass(element, 'visible');Check if element has class.
if (MicroUI.hasClass(element, 'active')) {
  // ...
}Perform GET request.
MicroUI.get('/api/data', {
  headers: { 'Authorization': 'Bearer token' }
}).then(data => console.log(data));Perform POST request.
MicroUI.post('/api/users', { name: 'John' })
  .then(response => console.log(response));Generic AJAX request.
MicroUI.ajax({
  url: '/api/data',
  method: 'PUT',
  data: { id: 1, name: 'Updated' },
  headers: { 'Content-Type': 'application/json' }
}).then(response => console.log(response));Fade in an element.
MicroUI.fadeIn('.modal', 300, () => {
  console.log('Fade in complete');
});Fade out an element.
MicroUI.fadeOut('.modal', 300);Slide down animation.
MicroUI.slideDown('.dropdown', 400);Custom animation using Web Animations API.
MicroUI.animate('.box', {
  transform: ['scale(1)', 'scale(1.2)', 'scale(1)'],
  opacity: [1, 0.8, 1]
}, {
  duration: 1000,
  iterations: Infinity
});Create debounced function.
const search = MicroUI.debounce((query) => {
  console.log('Searching:', query);
}, 300);Create throttled function.
const handleScroll = MicroUI.throttle(() => {
  console.log('Scrolling');
}, 100);Merge objects.
const config = MicroUI.extend({}, defaults, userOptions);LocalStorage wrapper.
// Set
MicroUI.store.set('user', { name: 'John', age: 30 });
// Get
const user = MicroUI.store.get('user');
// Remove
MicroUI.store.remove('user');
// Clear all
MicroUI.store.clear();SessionStorage wrapper.
MicroUI.session.set('token', 'abc123');
const token = MicroUI.session.get('token');Create reusable component.
MicroUI.component('counter', {
  template: `
    <div class="counter">
      <button class="dec">-</button>
      <span class="value">{{count}}</span>
      <button class="inc">+</button>
    </div>
  `,
  
  state: {
    count: 0
  },
  
  methods: {
    increment() {
      this.state.count++;
      this.update();
    },
    decrement() {
      this.state.count--;
      this.update();
    }
  },
  
  events: {
    'click .inc': 'increment',
    'click .dec': 'decrement'
  },
  
  lifecycle: {
    created() {
      console.log('Component created');
    },
    mounted() {
      console.log('Component mounted');
    }
  }
});
// Mount component
MicroUI.mount('.app', 'counter', { count: 10 });Create event delegation namespace.
const cart = MicroUI.delegate('shoppingCart', {
  'click .add-to-cart': function(e) {
    console.log('Adding to cart');
  },
  'click .remove-item': function(e) {
    console.log('Removing item');
  }
});
// Add more handlers
cart.on('click', '.checkout', handleCheckout);
// Remove handlers
cart.off('click', '.add-to-cart');
// Destroy all
cart.destroy();microui/
├── dist/
│   ├── microui.js         # Development build
│   ├── microui.min.js     # Production build
│   └── microui.esm.js     # ES Module build
├── src/
│   ├── core/
│   │   ├── dom.js         # DOM utilities
│   │   ├── events.js      # Event system
│   │   ├── ajax.js        # AJAX utilities
│   │   └── utils.js       # Helper functions
│   ├── modules/
│   │   ├── animation.js   # Animation module
│   │   ├── storage.js     # Storage utilities
│   │   ├── component.js   # Component system
│   │   └── delegate.js    # Delegation system
│   └── index.js           # Main entry point
├── examples/
│   ├── basic.html         # Basic examples
│   └── advanced.html      # Advanced UI components (tabs, modals, dropdowns)
├── tests/
│   ├── dom.test.js
│   ├── events.test.js
│   └── ajax.test.js
├── llms.txt               # LLM-friendly codebase documentation
├── package.json
├── rollup.config.js       # Build configuration
├── README.md
└── LICENSE
- Node.js 14+
 - npm or yarn
 
# Clone repository
git clone https://github.com/lam0819/microui.git
cd microui
# Install dependencies
npm install
# Development build
npm run build:dev
# Production build
npm run build
# Watch mode
npm run watch
# Run tests
npm test
# Run examples server
npm run serveThe project uses Rollup for building:
// rollup.config.js
import { terser } from 'rollup-plugin-terser';
import babel from '@rollup/plugin-babel';
export default [
  // Development build
  {
    input: 'src/index.js',
    output: {
      file: 'dist/microui.js',
      format: 'umd',
      name: 'MicroUI'
    },
    plugins: [
      babel({ babelHelpers: 'bundled' })
    ]
  },
  // Production build
  {
    input: 'src/index.js',
    output: {
      file: 'dist/microui.min.js',
      format: 'umd',
      name: 'MicroUI'
    },
    plugins: [
      babel({ babelHelpers: 'bundled' }),
      terser()
    ]
  },
  // ES Module build
  {
    input: 'src/index.js',
    output: {
      file: 'dist/microui.esm.js',
      format: 'es'
    },
    plugins: [
      babel({ babelHelpers: 'bundled' })
    ]
  }
];# Run all tests
npm test
# Run specific test file
npm test dom.test.js
# Run with coverage
npm run test:coverage
# Watch mode
npm run test:watch// tests/dom.test.js
import { describe, it, expect } from '@jest/globals';
import MicroUI from '../src/index.js';
describe('DOM Utilities', () => {
  it('should add classes', () => {
    const element = document.createElement('div');
    MicroUI.addClass(element, 'active highlight');
    
    expect(element.classList.contains('active')).toBe(true);
    expect(element.classList.contains('highlight')).toBe(true);
  });
  
  it('should query elements', () => {
    document.body.innerHTML = '<div class="test"></div>';
    const element = MicroUI.$('.test');
    
    expect(element).toBeTruthy();
    expect(element.className).toBe('test');
  });
});- Interactive Demo Site - Complete showcase with all features
 - Basic Examples - Core functionality demonstrations
 - Advanced Components - Tabs, modals, dropdowns, accordions, and more
 
<!DOCTYPE html>
<html>
<head>
  <script src="https://cdn.jsdelivr.net/gh/lam0819/MicroUI@latest/dist/microui.min.js"></script>
  <style>
    .todo { padding: 10px; margin: 5px; background: #f0f0f0; }
    .todo.completed { opacity: 0.5; text-decoration: line-through; }
  </style>
</head>
<body>
  <div class="app">
    <h1>Todo List</h1>
    <form class="todo-form">
      <input type="text" class="todo-input" placeholder="Add todo...">
      <button type="submit">Add</button>
    </form>
    <div class="todos"></div>
  </div>
  <script>
    MicroUI.ready(() => {
      // Handle form submission
      MicroUI.on('submit', '.todo-form', function(e) {
        e.preventDefault();
        
        const input = MicroUI.$('.todo-input');
        const text = input.value.trim();
        
        if (text) {
          const todoId = Date.now();
          MicroUI.append('.todos', `
            <div class="todo" data-id="${todoId}">
              <input type="checkbox" class="todo-check">
              <span class="todo-text">${text}</span>
              <button class="todo-delete">Delete</button>
            </div>
          `);
          
          input.value = '';
          
          // Save to storage
          const todos = MicroUI.store.get('todos') || [];
          todos.push({ id: todoId, text, completed: false });
          MicroUI.store.set('todos', todos);
        }
      });
      
      // Handle checkbox
      MicroUI.on('change', '.todo-check', function() {
        const todo = MicroUI.closest(this, '.todo');
        MicroUI.toggleClass(todo, 'completed', this.checked);
        
        // Update storage
        const todoId = parseInt(todo.dataset.id);
        const todos = MicroUI.store.get('todos') || [];
        const index = todos.findIndex(t => t.id === todoId);
        if (index !== -1) {
          todos[index].completed = this.checked;
          MicroUI.store.set('todos', todos);
        }
      });
      
      // Handle delete
      MicroUI.on('click', '.todo-delete', function() {
        const todo = MicroUI.closest(this, '.todo');
        const todoId = parseInt(todo.dataset.id);
        
        // Fade out and remove
        MicroUI.fadeOut(todo, 300, () => {
          MicroUI.remove(todo);
          
          // Update storage
          let todos = MicroUI.store.get('todos') || [];
          todos = todos.filter(t => t.id !== todoId);
          MicroUI.store.set('todos', todos);
        });
      });
      
      // Load saved todos
      const savedTodos = MicroUI.store.get('todos') || [];
      savedTodos.forEach(todo => {
        MicroUI.append('.todos', `
          <div class="todo ${todo.completed ? 'completed' : ''}" data-id="${todo.id}">
            <input type="checkbox" class="todo-check" ${todo.completed ? 'checked' : ''}>
            <span class="todo-text">${todo.text}</span>
            <button class="todo-delete">Delete</button>
          </div>
        `);
      });
    });
  </script>
</body>
</html><!DOCTYPE html>
<html>
<head>
  <script src="https://cdn.jsdelivr.net/gh/lam0819/MicroUI@latest/dist/microui.min.js"></script>
</head>
<body>
  <div id="app"></div>
  <script>
    // Define counter component
    MicroUI.component('counter', {
      template: `
        <div class="counter" style="padding: 20px; border: 1px solid #ddd; margin: 10px;">
          <h3>{{title}}</h3>
          <button class="dec">-</button>
          <span style="margin: 0 20px; font-size: 24px;">{{count}}</span>
          <button class="inc">+</button>
          <button class="reset">Reset</button>
        </div>
      `,
      
      props: {
        title: 'Counter',
        initial: 0
      },
      
      state: {
        count: 0
      },
      
      methods: {
        increment() {
          this.state.count++;
          this.update();
        },
        decrement() {
          this.state.count--;
          this.update();
        },
        reset() {
          this.state.count = this.props.initial;
          this.update();
        }
      },
      
      events: {
        'click .inc': 'increment',
        'click .dec': 'decrement',
        'click .reset': 'reset'
      },
      
      lifecycle: {
        created() {
          this.state.count = this.props.initial;
        }
      }
    });
    
    // Mount multiple counters
    MicroUI.mount('#app', 'counter', { title: 'Products', initial: 0 });
    MicroUI.mount('#app', 'counter', { title: 'Users', initial: 100 });
    MicroUI.mount('#app', 'counter', { title: 'Orders', initial: 50 });
  </script>
</body>
</html>We welcome contributions! Please see our Contributing Guide for details.
- Fork the repository
 - Create a feature branch: 
git checkout -b feature/my-feature - Make your changes
 - Add tests for new functionality
 - Run tests: 
npm test - Commit changes: 
git commit -m "Add my feature" - Push to branch: 
git push origin feature/my-feature - Submit a pull request
 
- Use ES6+ features
 - Follow ESLint configuration
 - Add JSDoc comments for public APIs
 - Keep functions small and focused
 - Write tests for new features
 
- Update README.md for user-facing changes
 - Update 
llms.txtfor codebase architecture changes - Add examples for new features
 - Include JSDoc comments for all public APIs
 
MIT License - see LICENSE file for details.
Created by MicroUI
Inspired by jQuery's simplicity and modern JavaScript best practices.