npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@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