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

haori

v0.6.0

Published

A lightweight HTML-first UI engine powered by declarative data bindings and expressions.

Readme

Haori.js

Haori.js is a lightweight, HTML-first UI library that enables dynamic user interfaces primarily through HTML attributes. It lets you declare data bindings, conditional rendering, list rendering, form two-way binding, server fetches, and HTML imports without writing much JavaScript.

Version: 0.6.0


Contents

  • Overview
  • Installation
  • Quick start
  • Common attributes (summary)
  • Build & publish
  • License & contributing
  • Further documentation

Overview

  • Design principle: HTML-first — declare UI behavior with HTML attributes
  • Keep internal state authoritative; let the rendered DOM follow asynchronously
  • Key features:
    • Data binding via data-bind
    • Conditional rendering via data-if
    • List rendering via data-each
    • Two-way form binding (automatic binding based on name attributes)
    • Boolean checkbox support with value="true" (true when checked, false when unchecked)
    • Server fetches via data-fetch
    • HTML imports via data-import
    • Zero runtime dependencies (uses browser-native APIs)

Runtime mode can be distinguished with data-runtime and Env.runtime when you need different behavior for embedded use and browser demos.

Installation

Install from npm:

npm install haori

Via CDN:

<script src="https://cdn.jsdelivr.net/npm/haori/dist/haori.iife.js"></script>

This CDN URL follows the latest published npm release.

ES Module import:

import Haori from 'haori';

Quick start

You can use Haori with plain HTML. Minimal example:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Haori Sample</title>
    <script src="https://cdn.jsdelivr.net/npm/haori/dist/haori.iife.js"></script>
  </head>
  <body>
    <div data-bind='{"name":"Taro"}'>
      <p>Hello, {{name}}</p>
    </div>
  </body>
</html>

Mounting from JavaScript:

import Haori from 'haori';

Haori.mount(document.body, {items: [{name: 'apple'}, {name: 'orange'}]});

Common attributes (summary)

  • data-bind — set binding data for an element (JSON or parameter format)
  • {{ ... }} — template expressions (evaluated and inserted)
  • data-if — show/hide an element based on a condition
  • data-each — repeat an element for items in an array (data-each-key, data-each-arg, data-each-index)
  • data-attr-xxx — safely update browser-interpreted attributes such as src and value
  • data-fetch — fetch data from a server and bind the result
  • data-import — load external HTML and insert it
  • data-url-param — import URL query parameters into bindings

Additional binding helpers:

  • data-derive / data-derive-name — define a derived value on an element and expose it to descendants only. This is useful for cases such as parent-child selects; see docs/ja/data-derive-confirmation-draft.md for the design background.

Template expressions support safe JavaScript-like syntax such as property access, bracket access with dynamic indexes, optional chaining, ternary expressions, and method chains including array map/filter with arrow functions and spread calls. Access to global objects, eval or arguments, and prototype escape paths such as constructor, __proto__, prototype, or Reflect is blocked.

data-fetch and data-import are automatically re-evaluated only when their evaluated values change after a binding update. data-fetch compares a request signature composed of the resolved URL, HTTP method, headers, and body, while data-import compares only the resolved URL. If either attribute contains even one unresolved reference, it is treated as invalid for that evaluation cycle, is not executed, and becomes executable only after a later binding update resolves the reference.

When the browser interprets an attribute during HTML parsing, such as src or value on input type="number", writing template expressions directly in that attribute can cause warnings or unwanted requests before Haori runs. Use data-attr-* for those cases. data-attr-xxx updates only the matching xxx attribute and does not synchronize DOM properties such as input.value.

For detailed usage and many examples, see the official documentation.


Build & publish (packaging)

Basic local verification and release preparation steps:

Quick release memo:

  1. Run npm run test, npm run build, and npm pack --dry-run.

  2. Bump the package version with npm version patch or the intended version command.

  3. Push main and tags with git push origin main and git push origin --tags.

  4. Publish a GitHub Release from the new version tag.

  5. Confirm npm, jsDelivr, and the GitHub Release assets reflect the new version.

  6. Install dependencies

npm install
  1. Type-check and test
npm run compile
npm run test
  1. Build release artifacts
npm run build
  1. Bump version
npm version patch
  1. Push the version update and tags
git push origin main
git push origin --tags
  1. Publish a GitHub Release from the new tag

Publishing to npm is handled by GitHub Actions when a GitHub Release is published. This repository uses release workflows that trigger on release.published, build the package, publish it to npm with NPM_TOKEN if that package version is not already published, and upload dist.zip to the release assets.

Required repository setup:

  • NPM_TOKEN must be configured in GitHub Actions repository secrets.
  • The release must be published from the target version tag.

Recommended pre-release checks:

  • npm run test
  • npm run build
  • npm pack --dry-run

Make sure package.json fields name, version, description, repository and license are correct. Files published to npm are controlled by the files field in package.json.


License & Contributing

  • License: MIT (see LICENSE in this repository)

Contributions are welcome — please open issues or pull requests on the GitHub repository.


Further documentation

For more detailed usage, attribute specs, and internal design, see:

  • docs/ja/guide.md — User guide (many examples)
  • docs/ja/specs.md — Technical specifications (internal design, API)
  • docs/ja/data-derive-confirmation-draft.md — Design background for scoped derived bindings and stable parent-child select composition

If you would like additional sections (API reference, diagrams, more examples), tell me what to include and I will expand the README.