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

@madojs/mado

v0.10.1

Published

Mado — a calm browser-native SPA framework for internal tools, admin panels and business apps. Routing, forms, state and data fetching without frontend infrastructure overhead.

Readme

Mado

A calm frontend stack for internal tools, admin panels and business SPA.

npm CI Browser Regression License: MIT

Mado is a browser-native SPA framework for teams that want routing, forms, data fetching and state management — without turning their frontend into an infrastructure project.

You write TypeScript, run tsc, and open the browser. No JSX transform, no Vite required, no hidden build pipeline. The entire runtime is readable in an evening. When something breaks, you can read the source and fix it.

Mado () means "window" in Japanese: a calm window into your app, without dragging a whole frontend factory into the room.

When to use Mado

  • Admin panels and dashboards — forms, tables, filters, auth, role guards.
  • Internal tools and backoffice — CRUD workflows, settings, billing UI.
  • Small SaaS frontends — where long-term maintainability matters more than ecosystem size.
  • Embedded widgets — where small footprint and independence from host frameworks matter.

The common thread: apps where the frontend should not become its own infrastructure problem.

When not to use Mado

  • SEO-heavy public sites that need SSR with hydration.
  • Large teams optimizing for hiring compatibility — React/Vue have bigger talent pools.
  • Projects that need a mature UI-kit ecosystem comparable to React today.
  • Beginners learning frontend — React, Vue and Svelte have far larger learning resources.
  • Teams uncomfortable with a pre-v1 framework — Mado is honest about its stage.

What Mado will not build

Mado stays useful by saying no. These are intentionally out of scope:

  • SSR with hydration. Use bake or edge prerender for SEO-oriented static output.
  • A template compiler, JSX transform, or VDOM compatibility layer.
  • A separate store library. Use signal(), computed() and resource().
  • Suspense primitives or a router plugin system.
  • Built-in i18n, animation, or virtual-scroll primitives.
  • Non-evergreen browser support. The baseline is modern evergreen browsers with Baseline 2023 platform features.

Why teams pick Mado

| What matters to you | Best choice | |---|---| | Largest ecosystem, most hires available | React or Vue | | Reusable design-system components across host frameworks | Lit | | Maximum rendering performance, JSX workflow | Solid or Svelte 5 | | Progressive enhancement of server-rendered pages | htmx + your backend | | Full app stack with minimal infrastructure and calm maintenance | Mado |

Honest tradeoffs:

  • vs Lit — Lit is better for design systems. Mado is for whole apps: router, data, forms and prerender in one package, no assembly required.
  • vs Solid — Solid is faster and more mature. It also requires Vite + a babel plugin. Mado requires nothing but tsc.
  • vs htmx — htmx is excellent when your backend owns HTML. Mado is for cases where you want a real SPA: local state, optimistic updates, cached resources, lazy modules and persisted UI state.

What you get

Routing, forms, state, data fetching and prerendering — without ecosystem tax:

  • No runtime dependencies to audit, update or break
  • No bundler required to start (tsc is enough)
  • Fewer moving parts to debug
  • Compact API surface you can learn in a day
  • Lower long-term cognitive load
Runtime budget:
  enforced in CI with npm run size
Runtime dependencies: 0
Required dev dependencies: typescript, esbuild, linkedom

Quick Start

Start a new app

npm exec --package @madojs/mado@latest -- mado init my-app
cd my-app
npm install
npm run dev

The admin starter gives you the blessed production shape: layouts, guards, auth/API client, forms and a small admin shell.

npm exec --package @madojs/mado@latest -- mado init dashboard --starter admin
cd dashboard
npm install
npm run dev

The CRUD starter is a compact resource/mutation/forms example:

npm exec --package @madojs/mado@latest -- mado init my-app --starter crud

Try the flagship example

git clone https://github.com/madojs/mado.git
cd mado
npm install
npm run build
npm run serve -- showcase

The showcase is a CRM-shaped pressure app with auth, tables, filters, nested routes, context services, forms and real data patterns.

How it works

Signals — reactive state

import { signal, computed, effect } from "@madojs/mado";

const count = signal(0);
const doubled = computed(() => count() * 2);
effect(() => console.log(count()));

count.set(1);

Signals are getter functions: read with count(), write with count.set(v) or count.update(fn).

Templates — tagged template html

html`<button @click=${fn} ?disabled=${loading} class=${cls}>${label}</button>`;
  • ${value} — child content (text, nodes, arrays, nested html, each)
  • @event=${fn} — event listener
  • attr=${v} — attribute
  • .prop=${v} — DOM property
  • ?attr=${flag} — boolean attribute
  • Functions and signals are tracked reactively

Components — Web Components

import { component, css, html } from "@madojs/mado";

component(
  "x-card",
  () => () => html`<section><slot></slot></section>`,
  {
    styles: css`:host { display: block; padding: 1rem; }`,
  },
);

Routing — file-based-free

import { routes } from "@madojs/mado";

export default routes({
  "/": () => import("./pages/home.js"),
  "/users/:id": () => import("./pages/user-detail.js"),
  "*": () => import("./pages/not-found.js"),
});

Lazy loading, nested routes, query params, guards, hover prefetch, scroll restoration, error boundary, View Transitions.

Data — resource + mutation

import { resource, mutation, invalidate, jsonFetcher } from "@madojs/mado";

const user = resource(
  () => `/api/users/${userId()}`,
  jsonFetcher<User>(),
  { staleTime: 60_000 },
);

const save = mutation(api.saveUser, {
  invalidates: ["/api/users*"],
});

Cache, loading/error state, abort, refresh, optimistic mutate(), glob-based invalidation. Lifecycle-aware inside components.

Resource keys are the cache identity. Use keys that include the endpoint, params and data shape; two resources with the same key share cached data and in-flight requests.

Forms — schema-based validation

import { useForm, html } from "@madojs/mado";

const form = useForm({
  email: { required: true, type: "email" },
  age: { type: "number", min: 18 },
});

html`
  <form @submit=${form.onSubmit(async (values) => api.save(values))}>
    <input name="email" @input=${form.onInput} @blur=${form.onBlur}>
    <button ?disabled=${() => !form.isValid() || form.submitting()}>Save</button>
  </form>
`;

HTML-like constraints (required, min, max, pattern, type), async validators, field arrays. Close to the platform, not fighting it.

Lists — keyed reconciliation

import { each } from "@madojs/mado";

html`<ul>${() => each(items(), (item) => item.id, (item) => html`<li>${item.name}</li>`)}</ul>`;

Static prerender — SEO without SSR

mado release

Build-time prerender of routes into static HTML with meta tags and JSON-LD. No hydration runtime. For dynamic content, see the Cloudflare edge-prerender PoC in examples/cloudflare.

Production

mado release    # typecheck + build + bundle + bake + promote baked HTML + copy public -> out/
mado preview    # serve out/ like a static host

One command, one artifact (out/). Upload anywhere: VPS, Cloudflare Pages, any static CDN.

CLI

mado init my-app              # scaffold new app
mado init dashboard --starter admin
mado dev                      # dev server with hot reload
mado build                    # tsc compile
mado typecheck                # type check without emit
mado test                     # run test suite
mado release                  # full production build
mado preview                  # serve production build locally

Documentation

Localized docs: French · Ukrainian · Russian

AI-agent entrypoints: AGENTS.md · llms.txt

Examples

Known Limits

| Limit | What it means | |---|---| | No SSR hydration | Use bake or edge prerender for SEO. Server rendering is out of scope. | | Small ecosystem | No UI-kit or plugin marketplace. You own your components. | | Pre-v1 API | Public API is small and intentional, but may change before v1. | | Evergreen browsers only | Modern Chrome, Edge, Firefox, Safari. No IE/legacy. | | Template IDE support | `html`` highlighting needs lit-plugin or similar. |

Tests

npm run typecheck
npm run build
npm test
npm run test:browser

Covers signals, computed, effects, html parser, keyed reconciliation, resources, mutations, forms, router isolation, component lifecycle and example smoke tests.

Contributing

Read CONTRIBUTING.md. Bug fixes with tests, docs improvements, examples and carefully discussed core changes are welcome. Runtime dependencies are not.

License

MIT.