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

danio-js

v0.1.0

Published

A fast, dependency-free frontend framework built from scratch: fiber reconciler, hooks, store, and router. If you know React, you know Danio.

Readme


Danio is a fast, tiny, dependency-free frontend framework built from scratch in plain JavaScript — a virtual DOM, a fiber reconciler with bailouts, hooks, a store, and a router, in about 2,000 lines you can read in an afternoon. It isn't a wrapper around React or a fork of Preact; it's the whole engine, written to be understood. If you know React, you already know Danio.

🌐 Website  ·  📖 Documentation  ·  🎨 Brand kit

import { render, useState } from 'danio-js'

function Counter() {
  const [n, setN] = useState(0)
  return <button onClick={() => setN(n + 1)}>clicked {n} times</button>
}

render(<Counter />, document.getElementById('root'))

Quick start

# scaffold a new app (Vite + JSX + example + TypeScript types)
npm create danio@latest my-app
cd my-app && npm run dev

# …or add Danio to an existing project
npm install danio-js

To compile JSX, point your bundler at Danio's runtime. With Vite:

// vite.config.js
export default {
  esbuild: { jsx: 'automatic', jsxImportSource: 'danio-js' },
}

Full setup, including a jsconfig.json for editor autocomplete, is in the Guide.

Why Danio

  • Tiny — the whole framework is ~8 kB gzipped with zero runtime dependencies.
  • Familiar — components, JSX, useState, useEffect, context, a Redux-style store, a router. Nothing new to learn, only less of it.
  • Readable — every file is plain, commented JavaScript. Open node_modules/danio-js/src and the framework is right there. Danio even ships its source, on purpose.
  • Fast — a fiber reconciler with bailouts means a setState re-renders one component, not the whole tree (~200× faster updates on a 500-row benchmark).
  • Complete — hooks, context, memo, error boundaries, a store with middleware, a History-API router, SSR + hydration, and TypeScript types. All included.
  • Honest — the docs tell you where Danio doesn't fit (see below), not just where it does.

A fuller taste

State, a store, and routing — all from one import:

import {
  render, useState, useEffect,
  createStore, StoreProvider, useSelector, useDispatch,
  Router, Routes, Route, Link,
} from 'danio-js'

function Todos() {
  const todos = useSelector((s) => s.todos)
  const dispatch = useDispatch()
  return (
    <ul>
      {todos.map((t) => (
        <li key={t.id} onClick={() => dispatch({ type: 'toggle', id: t.id })}>
          {t.text}
        </li>
      ))}
    </ul>
  )
}

render(
  <StoreProvider store={store}>
    <Router>
      <nav><Link to="/">Home</Link> <Link to="/todos">Todos</Link></nav>
      <Routes>
        <Route path="/" component={Home} />
        <Route path="/todos/:id" component={TodoDetail} />
      </Routes>
    </Router>
  </StoreProvider>,
  document.getElementById('root'),
)

Server-side rendering

Render to HTML for SEO and first paint, then hydrate on the client. renderToString runs in plain Node with no DOM:

// server
import { renderToString } from 'danio-js/server'
res.send(`<div id="root">${renderToString(<App />)}</div>`)

// client
import { hydrate } from 'danio-js'
hydrate(<App />, document.getElementById('root'))

hydrate reuses the server DOM instead of rebuilding it. See the SSR section of the Guide.

Where Danio fits

Danio is the right call when size, control, and understanding matter more than a giant ecosystem — size-critical or embedded UIs, controlled internal platforms, or simply learning how a framework actually works.

Reach for something else when you need streaming SSR or React Server Components today, depend on a large third-party ecosystem or hiring pool, or want the absolute fastest runtime (a signals framework like Solid will edge it). A framework's real cost is its ecosystem, and React's is enormous — Danio doesn't try to out-React React.

Documentation

  • Guide — install, components, hooks, store, router, SSR, and deployment.
  • How it's built — the guided tour of the engine: fibers, bailouts, scheduling, and the problems every framework has to solve.
  • Brand & logo — the Danio mark and palette.

What's included

| | | |---|---| | Rendering | virtual DOM, fiber reconciler, keyed diffing, render/commit split | | Hooks | useState, useReducer, useEffect, useLayoutEffect, useMemo, useCallback, useRef | | Context | createContext, useContext | | Performance | bailouts, memo, shallowEqual | | Errors | <ErrorBoundary> catching render and effect errors | | Store | createStore, combineReducers, applyMiddleware, thunk, logger, useSelector | | Router | <Router>, <Routes>, <Route>, <Link>, useParams, useNavigate | | Server | renderToString, renderToStaticMarkup, hydrate | | Tooling | JSX automatic runtime, TypeScript types, create-danio scaffolder |

Not yet: streaming SSR, React Server Components, portals, and Suspense. Tested against a real DOM (54 unit tests) and a headless-browser pass in Chrome; Safari and Firefox are untested so far.

Develop

npm install      # Vite + jsdom, both dev-only
npm run dev      # http://localhost:5173 — the example app
npm test         # 54 tests against a real DOM
npm run bench    # the bailout benchmark
npm run build    # production build -> dist/

License

MIT