@nbaloshi/nbaloshi-framework
v1.0.2
Published
Welcome to **MiniFramework** – a lightweight JavaScript framework for building reactive, single-page applications using pure JavaScript.
Readme
MiniFramework
Welcome to MiniFramework – a lightweight JavaScript framework for building reactive, single-page applications using pure JavaScript.
This framework was built from scratch to provide:
- DOM Abstraction using virtual JSON-based element trees
- Reactive State Management
- Client-side Routing System (with History API)
- Declarative Event Handling
This documentation explains how the framework works, and provides code examples for using it in your projects – including how to build the classic TodoMVC app.
All examples are written in pure JavaScript or TypeScript, with no dependencies.
Feature Overview
1. DOM Abstraction
Write DOM as structured JS objects and render them via myCreateElement.
2. Event Handling
Attach DOM events using an events object, not addEventListener.
3. State Management
Manage shared app state with the StateManager class, supporting reactivity.
4. Routing
Synchronize app state with the browser's URL using a simple Router.
Continue reading for detailed usage and examples.
DOM Abstraction
MiniFramework uses a JSON-like structure to define HTML elements.
All elements follow the FrameworkElement format:
interface FrameworkElement {
tag: string;
attrs?: { [key: string]: string };
children?: (FrameworkElement | string)[];
events?: { [eventType: string]: (e: Event) => void };
}
1. Create an Element
const title = {
tag: "h1",
children: ["Hello, world!"]
};
2. Add Attributes to an Element
const input = {
tag: "input",
attrs: {
type: "text",
placeholder: "Enter your name",
class: "input-name"
}
};
3. Nest Elements
const form = {
tag: "div",
attrs: { class: "form-group" },
children: [
{
tag: "label",
children: ["Your name:"]
},
{
tag: "input",
attrs: {
type: "text",
placeholder: "Name"
}
}
]
};
4. Rendering the Element
import { myCreateElement } from '@nbaloshi/nbaloshi-framework';
const app = document.getElementById("app");
app.appendChild(myCreateElement(form));
# Event Handling
MiniFramework supports declarative event handling via the `events` object inside any `FrameworkElement`.
---
## Example: Click Event
``ts
const button = {
tag: "button",
attrs: { class: "btn" },
children: ["Click Me"],
events: {
click: () => {
alert("Button clicked!");
}
}
};
Example - Input Keydown Event
const input = {
tag: "input",
attrs: {
type: "text",
placeholder: "Type something"
},
events: {
keydown: (e) => {
console.log("Key pressed:", e.key);
}
}
};
# State Management
MiniFramework includes a simple but powerful **reactive state manager** that enables shared, observable application state.
This system allows you to:
- Define a centralized store
- Read the current state
- Update state reactively
- Subscribe to state changes
---
## Create a Store
To create a new state store, instantiate the `StateManager` class with your desired initial state:
```ts
import { StateManager } from '@nbaloshi/nbaloshi-framework';
const store = new StateManager({
count: 0
});
Use .getState() to read the current value of the state at any time:
const current = store.getState();
console.log(current.count);
Use .setState() to update one or more fields in the state. The update is shallow-merged into the existing state:
store.setState({ count: current.count + 1 });
Use .subscribe() to listen for state changes. The callback will be called immediately with the current state, and again every time the state updates:
const unsubscribe = store.subscribe((newState) => {
console.log("State changed:", newState);
});
// To stop listening:
unsubscribe();
``markdown
# Routing
MiniFramework includes a minimal routing system using the browser's History API.
---
## Create Routes
``ts
import { router } from '@nbaloshi/nbaloshi-framework';
router.add('/', () => {
console.log("Home route");
});
router.add('/about', () => {
console.log("About page");
});
## Navigate Programmatically
router.navigate('/about');
## Initialize Router
router.init();
This will read the current URL and trigger the matching route callback.
## Example - Filter Todos by URL
router.add('/completed', () => {
todoStore.setState({ filter: "completed" });
});
``markdown
# How the Framework Works
MiniFramework was designed to reverse the traditional control of code.
Instead of the developer controlling the DOM and state directly, **the framework is in control and calls your code** through:
---
## 1. DOM Abstraction
All UI is defined using a virtual element structure (`FrameworkElement`).
These are passed to `myCreateElement()` which recursively creates actual DOM nodes.
---
## 2. Custom Event System
Instead of `addEventListener`, event handlers are passed as part of the element object.
This keeps UI logic and structure tightly coupled, and easily testable.
---
## 3. Reactive State
The `StateManager` holds global state and notifies subscribers when the state changes.
---
## 4. Routing
The `Router` syncs the app’s state and UI with the browser’s address bar.
It listens to `popstate` and can programmatically push state with `navigate()`.
---
## Summary
MiniFramework is **unopinionated, minimal**, and focuses on:
- Reactivity
- Declarative UIs
- Simplicity