A lightweight framework built to understand the core concepts of modern JavaScript frameworks. It implements core features like:
- π― Virtual DOM Rendering
- π State Management
- π£οΈ Client-side Routing
- π‘ Event Handling System
A complete TodoMVC application has been built using Mini-Framework to demonstrate its capabilities.
TodoMVC is a popular project that provides the same simple "To-Do List" application built using different frontend frameworks and libraries (like React, Vue, Angular, Svelte, etc.) but we are using our own Mini-Framework that's the whole purpose of this project
- β Add, edit, and delete todos
- π Filter todos (All, Active, Completed)
- π Track remaining items
- π§Ή Clear completed todos
- πΎ Persistent storage
When you open the index.html you will see a simple TodoMVC application, saying What needs to be done?
You can enter anything for an example, homework - buying grocieries - etc.
There's an All bar, Active bar, and Completed bar to filter the todos.
After you complete your task and tick your todo off you can clear off completed todos by clicking on clear Completed, or you can simply see the cleared tasks in completed bar.
You can also edit your todos by double-clicking on them and entering a new value.
-
π
addEvent(el, eventName, handler)- Entry point of the system
- Registers custom events (e.g., onClick) for DOM elements
- Creates new handler arrays in eventRegistry for new event types
-
π Event Registry
- Tracks elements and their event handlers
- Stores
{ element, fn }objects in arrays, keyed by eventName
-
π§ Document Event Listener
- Adds a single global listener for new event types
- Handles native browser event delegation
-
π₯ Event Flow
- Browser fires native event (e.g., click)
- System captures and processes the event
-
π Event Matching
- Checks eventRegistry[eventName] array
- Matches event.target against registered elements
-
β Handler Resolution
- Matching element found β calls associated handler
- No match β event is ignored
-
β‘ Handler Execution
- Executes fn(e) for matching elements
- Completes the event cycle
-
π§ Virtual DOM Creation:
h(tag, attrs, ...children)- Creates virtual DOM elements (similar to React's createElement)
- Parameters:
tag: HTML element type (e.g., 'div')attrs: Element attributes (id, class, onClick, etc.)children: Nested elements or text content
-
πΌοΈ Rendering:
render(vnode, container)- Main rendering pipeline
- Clears existing container content
- Converts virtual nodes to real DOM
- Mounts elements to the container
-
ποΈ DOM Element Creation:
_createElement(vnode)- Converts virtual nodes to real DOM elements
- Handles both text nodes and element nodes
- Creates DOM hierarchy recursively
-
π§ Text Node Processing
- Detects string/number nodes
- Creates text nodes via
document.createTextNode() - Optimizes text content rendering
-
π·οΈ Attribute Management
- Sets DOM element attributes
- Special handling for event listeners (on*)
- Uses custom event system for interactions
-
𧬠Child Element Processing
- Recursively processes child elements
- Maintains parent-child relationships
- Builds complete DOM tree structure
const vnode = h('div', { class: 'container' },
h('h1', { onClick: () => alert('Hello!') }, 'Hello World'),
h('p', {}, 'Welcome to Mini-Framework')
);
render(vnode, document.getElementById('app'));-
πΊοΈ Route Definition
defineRoutes({ '/': HomePage, '/about': AboutPage, '/404': NotFoundPage });
- Define available routes using a routeTable object
- Keys are paths (/, /about, /404)
- Values are component functions
-
π¦ Router Initialization
startRouter(document.getElementById('app'), render);
- Initializes routing system
- Stores root DOM element
- Sets up hashchange event listener
- Triggers initial route
-
π Route Processing
- Listens for URL hash changes
- Extracts clean path from hash
- Matches path to route table
- Renders appropriate component
-
π― Path Resolution
- Removes '#' prefix from hash
- Defaults to '/' for empty hash
- Handles 404 for unknown routes
-
πΌοΈ Page Rendering
- Calls matched route function
- Creates virtual DOM
- Renders to root element
-
π± Navigation API
// Programmatic navigation navigate('/about'); // Changes URL to #/about // Link-based navigation h('a', { href: '#/about' }, 'About Page')
// Define routes
defineRoutes({
'/': () => h('div', {}, 'Home Page'),
'/about': () => h('div', {}, 'About Us'),
'/404': () => h('div', {}, 'Page Not Found')
});
// Initialize router
startRouter(document.getElementById('app'), render);
// Create navigation menu
const Nav = () => h('nav', {},
h('a', { href: '#/' }, 'Home'),
h('a', { href: '#/about' }, 'About')
);-
ποΈ State Initialization
createState({ count: 0, theme: 'dark' });
- Creates global state store
- Copies initial state object
- Sets up listener system
-
π¦ State Updates
setState({ count: count + 1 });
- Merges new state with existing
- Creates new state object
- Triggers update cycle
-
π Subscription System
subscribe(state => { console.log('State updated:', state); });
- Registers listener functions
- Automatically called on updates
- Receives latest state
-
π Update Cycle
- State changes trigger listeners
- Components can re-render
- Updates flow through app
-
π± Component Integration
function Counter() { const state = getState(); return h('div', {}, h('span', {}, state.count), h('button', { onClick: () => setState({ count: state.count + 1 }) }, '+') ); }
// Initialize state
createState({
count: 0,
theme: 'light',
user: null
});
// Subscribe to changes
subscribe(state => {
render(App(), document.getElementById('app'));
});
// Update state
setState({ count: 1 });
setState({ theme: 'dark' });
// Get current state
const state = getState();-
π Immutable Updates
- State is never directly modified
- Updates create new state objects
- Previous state preserved
-
π― Predictable Flow
- One-way data flow
- State β View β Action β State
- Centralized state management
-
π Easy Integration
- Works with virtual DOM
- Automatic re-rendering
- Simple API



