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

@rgslabs/mini.js

v0.0.5

Published

Mini is a ~~library~~ extension for HTML which lets you add interactivity to your app without needing a full blown frontend framework.

Readme

Mini.js

Mini is a ~~library~~ extension for HTML which lets you add interactivity to your app without needing a full blown frontend framework.

The Idea

  • HTML is great because it's easy to learn and extremely accessible. But HTML has shortcomings when it comes to building interfaces with interactivity.
  • Lots of libraries have emerged to address these shortcomings - react, vue etc. These libraries are great but they:
    • Have a high learning curve when it comes to code patterns and tooling.
    • Are primarily suited for interfaces with lots of interactivity.
  • Mini JS lets you build interfaces with moderate amounts of interactivity without needing a heavyweight, javascript-centered library. Because it follows the same patterns as html, it doesn't require learning lots of new concepts. It's designed to be extremely minimal and learnable within an afternoon.
  • The key idea is that if we have
    1. A way to set state when an interaction happens (e.g a user clicks a button or types in an input), and
    2. A way to update other parts of the UI when those variables change, we can now easily do a range of things we previously couldn't do.
  • Technically vanilla HTML can already do (1), but it can't do (2).

Installation

To setup Mini.js in your local machine, you can do the following:

Clone the repository.

git clone https://github.com/reallygoodsoftware/mini.js.git

cd mini.js

Install the dependencies:

yarn

Running the development server

To run the development server, you can do the following:

yarn dev

This will start the development server at http://localhost:5173.

In another terminal, you can run the following to build the code whenever the Mini.js code changes:

# This will build the code whenever the Mini.js code changes
yarn build-watch

# This will build the code once
yarn build

Running the tests

To run the tests, you can do the following:

yarn test

Tests are automatically run when you push to the repository.

For browser tests, you can only run them locally by running:

yarn test:browser

Documentation

This is a quick overview of the features of Mini.js. For more details, please refer to the website at https://mini-js.com.

Old Mini.js

This is the old version of Mini.js which uses a lexer. It's not recommended to use this version. It's here for reference only.

https://github.com/reallygoodsoftware/minijs

Setting State

State are variables that changes the UI or the DOM that uses it when they get updated.

For Mini.js, the <state> tag is used to defined state variables. You can define a state variable like this:

<state first-name="Tony">
  <p js-text="firstName"></p>
</state>

The attribute first-name is the name of the state variable, and the value Tony is the initial value of the variable. The variables defined in the <state> tag are automatically available to it its children in their camelCase form.

Syncing the DOM with your state

These are the following dynamic attributes that you can use to sync the DOM with your state:

  • js-value
    • Set the value of a form input to the result of the evaluated JS code.
  • js-class
    • Set the class of a DOM element to the result of the evaluated JS code.
  • js-text
    • Set the text content of a DOM element to the result of the evaluated JS code.
<state first-name="Tony">
  <input type="text" js-change="firstName = this.value" />

  <!-- The innerText of this paragraph changes based on the firstName variable -->
  <p js-text="firstName"></p>
</state>

Triggering DOM Updates / Re-renders

A DOM update or a re-render happens when the state variable is re-assigned inside the dynamic events.

<input type="text" js-change="firstName = this.value" />
<!-- the re-assignment of firstName will trigger DOM updates that uses that variable -->

When re-assignment happens in dynamic attributes, it will not trigger a re-render to avoid infinite loops.

<p js-text="firstName = 'Tony'"></p>
<!-- the re-assignment of firstName will not trigger DOM updates -->

Special Variables & Methods

There are special variables and methods that you can use inside dynamic attributes and events:

  • this - the current element
  • $ - equal to the document.querySelector.
  • $$ - equal to the document.querySelectorAll.
  • wait - a method that waits for a given amount of time. Usage: <button js-click="await wait(1000); alert('Hello')">Click Me</button>

Dynamic Attributes

Besides js-value, js-class, and js-text, you can also make any attribute dynamic by renaming it from attribute to js-attribute. Values set to dynamic attributes are evaluated as JavaScript:

<state p-style="color: red">
  <p js-style="pStyle">My style is changing</p>
  <button
    js-click="if (pStyle === 'color: red')
              pStyle = 'color: blue';
            else
              pStyle = 'color: red'"
  >
    Toggle Style
  </button>
</state>

Classes

You can make your class names reactive by using the js-class attribute:

<state is-active="false">
  <button js-click="isActive = !isActive" js-class="isActive ? 'active' : ''">
    Click Me
  </button>
</state>
Smart Classes

For simple ternaries, js-class smartly evaluates the class names based on the base classes and the evaluated classes.

<state condition="true">
  <p
    class="text-red-500 text-sm font-mono"
    js-class="condition ? 'text-green-500' : 'text-red-500'"
  >
    This text is conditionally styled based on the state. I should be green!
  </p>
</state>
  • Base Class (class value): class="text-red-500 text-sm font-mono"
  • Dynamic Class value (js-class value): true ? 'text-green-500' : 'text-red-500'
  • Evaluated Result: text-sm font-mono text-green-500

Explanation:

You will notice that instead of text-sm font-mono text-red-500 text-green-500 you see text-sm font-mono text-green-500 only. This is because the js-class directive intelligently merges the base classes with the evaluated classes, resulting in a more concise class list without conflicts. It knows that text-red-500 should only apply when the condition is false. Thus it removes it from the final class. Without it, text-red-500 and text-green-500 would both be applied, leading to conflicting styles.

Events

You can create, use, and update state variables inside DOM events.

In events, you can get the current event using the event variable:

<button js-click="console.log(event)">Click Me</button>

Native Events

All native events are supported. You can use them like this:

<button js-click="console.log('click')">Click Me</button>

You can access the current element in the event via this:

<button js-click="this.classList.toggle('active')">Click Me</button>

<input js-change="this.value = this.value.toUpperCase()" />

Custom Events

These are the events added in by Mini.js:

  • js-clickout - This will trigger when the user clicks outside of the current element.
  • js-clickme - This will trigger when the user clicks the current element.
  • js-change - This will trigger when the user changes the value of a form input.
  • js-press - This will trigger when the user:
    • triggers the click event.
    • triggers the keyup events for Enter and Space keys.
    • triggers the touchstart event.

Variables

Variables saved in Local Storage

For local storage, you don't need to use the <state> tag. It can automatically be used in any element. Appending $ to the variable name will save the variable in the local storage:

<div>
  <input type="text" js-change="$firstName = this.value" />
  <p js-text="$firstName"></p>
</div>

El Variables

To use variables in the current element, you can use the el prefix. This is useful when you want to use a variable in the current element but not in its children.

<button
  js-mouseenter="el.text = 'Mouse Hovered!'"
  js-mouseleave="el.text = 'Mouse Left!'"
  js-click="el.text = 'Clicked!'"
  js-text="el.text"
>
  Click Me!
</button>
Local Variables

To use variables only in a current event, you can create a local variable using const, and let:

<button
  js-click="const time = new Date();
          alert(time.toLocaleTimeString())"
>
  Click Me
</button>

Contributors