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

@kudzujs/core

v0.16.37

Published

HTML-first TSX framework with synchronous state semantics and no virtual DOM

Readme

Kudzu

HTML-first TSX framework with synchronous state semantics and no virtual DOM.

Kudzu compiles ordinary React-shaped TypeScript and TSX into complete static HTML, CSS, and only the route-specific ESM capabilities actually used. Static pages ship zero JavaScript. React, hydration, a VDOM, and a retained browser component tree are not part of the output.

Watch the 22-second Kudzu compiler overview

Watch: React-shaped TSX to static HTML and route-specific ESM in 22 seconds.

Experimental 0.16.x: the compiler API and supported TSX surface may change.

Current release: 0.16.36. The optional create-kudzu --ai check tool now respects managed process-group cancellation while retaining its own timeout, failure reporting and full logs. Compiler/runtime behavior is unchanged; AI-token savings are unmeasured and the AI-cost/1.0 gates remain blocked.

Quick Start

Kudzu requires Node.js 22 or newer.

npm create kudzu@latest my-app
cd my-app
npm install
npm run dev

The generated project includes reusable components, an interactive state example, a zero-JavaScript static route, metadata, and responsive CSS.

For optional AI authoring guidance and local developer tools, use npm create kudzu@latest my-app -- --ai. The generated AGENTS.md describes npm run ai -- docs for installed documentation and npm run ai -- check for typecheck/build execution with bounded output and full retained logs. These tools stay outside default browser output. AI-token savings have not been measured. See the generator guide.

To add Kudzu to an existing project:

npm install @kudzujs/core typescript

Add the Kudzu commands to package.json:

{
  "scripts": {
    "dev": "kudzu dev",
    "build": "kudzu build",
    "check": "tsc --noEmit && kudzu build"
  }
}
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "jsx": "react-jsx",
    "jsxImportSource": "@kudzujs/core",
    "strict": true
  }
}

Put routes in src/pages; src/pages/index.tsx maps to /.

import { useState } from "@kudzujs/core"

export default function HomePage() {
  const [count, setCount] = useState(0)

  return <button onClick={() => setCount(count + 1)}>
    Grown {count} times
  </button>
}
npm run dev
npm run build

Authoring

Use native HTML controls and events. Read the control through event.currentTarget inside the handler and update state with its setter; Kudzu does not use React synthetic events. Setters update logical state immediately and batch DOM writes.

Keep derived values pure: top-level const locals can normalize primitive state, filter an immutable collection, and reuse its .length in JSX. Render ordinary child components with stable keys rather than manually rebuilding DOM rows. For example, with items exported as a JSON-safe immutable array from ../data and Item as a relative component rendering one item:

import { useState } from "@kudzujs/core"
import { items } from "../data"
import { Item } from "../Item"

export default function ItemsPage() {
  const [query, setQuery] = useState("")
  const normalized = query.trim().toLowerCase()
  const visible = items.filter(item => item.name.toLowerCase().includes(normalized))
  const count = visible.length

  return <main>
    <label htmlFor="item-query">Find items</label>
    <input id="item-query" type="search" value={query}
      onInput={event => setQuery(event.currentTarget.value)} />
    <p aria-live="polite">Matches: {count}</p>
    <ul>{visible.map(item => <Item key={item.id} item={item} />)}</ul>
  </main>
}

Collection aliases must stay within supported collection/count uses; arbitrary calls, mutation, and escaping reactive collections are not supported. Use the build's source-located diagnostic and current limits to identify the boundary rather than assuming arbitrary React code will compile.

Keep interactions in the routes that need them. Build-known direct imported maps and pure static filters can emit complete HTML without list JavaScript. A static sibling outside an enhanced-navigation group ships no JavaScript merely because another page is interactive. Shared layout effects or explicit navigation groups have their own lifetime; native anchors remain the default.

Verify

A successful build validates supported source and emits deployable outputs; it does not verify browser behavior or accessibility. Check visible DOM and relevant interactions, labels, status updates, keyboard focus, and responsive layouts in a browser as needed. Binding comments and inert templates mean raw HTML string matches or tag stripping are not reliable checks of rendered text.

Normal builds also scan generated route HTML after afterBuild, reporting counts with/without script or modulepreload text markers and unreadable files, with up to five paths per category (long paths are truncated). This is a literal text scan, not proof of script freedom: comments and inert content can match, inline event attributes are not checked, and extra public HTML files are outside the route inventory. Quiet and JSON builds omit this summary.

Keep checks bounded and report concise counts and failing paths rather than repeatedly dumping minified artifacts. A missing tool or truncated response is not a pass. After source changes, rerun affected checks. Optional compiler/artifact reports and their limits are documented under Build output.

How It Works

ordinary React-shaped TSX
  -> Kudzu compiler specialization
  -> complete HTML + CSS + capability-specific ESM
  • Function components execute at build time and do not survive as browser components.
  • useState and reduced useReducer, including directly serializable lazy initialization, compile to synchronous logical state and batched direct DOM writes; top-level useId and direct intrinsic forwardRef authoring erase to static HTML without a component runtime.
  • Conditions, keyed collections, attributes, events, refs, effects, and supported component boundaries compile to route-specific capabilities. A direct setter may cross one ordinary component boundary through one value-adapter event call; inline or simple const setter callbacks and object refs may cross the same direct intrinsic boundary.
  • Build-known data and routes become complete HTML through async components and getStaticPaths().
  • Native document navigation is the default; static routes do not load a client runtime.
  • A named or aliased React Router Link with a static root-relative to erases to a base-aware native anchor; no router package or runtime is emitted.
  • A direct named or aliased React Router useParams() call on a runtimeParams bracket route reuses Kudzu's route-specific pathname reader.
  • A direct top-level React Router useMatch("/exact-path") route binding folds case-insensitively from the build-known application route without browser JavaScript.
  • React Router useSearchParams() supports direct static get("name") locals, the exact numeric pagination fallback Number(params.get("page")) || 1, a static imported-array string fallback, and inline setter updaters, lowering reads and history writes to one route-specific query capability.
  • React Bootstrap Row and Col with children, static classes, and numeric literal Col breakpoints erase to native Bootstrap grid markup; applications retain ownership of Bootstrap CSS.
  • Browser-only query data uses owned effects with application loading/error/data state; URL-derived dependencies, stale-response isolation, keyed results, and recovery require no query package runtime.
  • Only TypeScript modules reachable from pages are compiled. Imported immutable direct maps can fold to static HTML, while direct fields from relative structured calculations reevaluate through route binding ESM.
  • Package imports used directly inside JSX event callbacks are removed from build modules and retained only in bundled route handler ESM.
  • A named or aliased React Router useNavigate() top-level binding lowers direct nested-callback calls with safe static root-relative destinations to native location.assign() or location.replace() navigation.
  • Unsupported nearby patterns fail during the build with a source location and actionable boundary.

Migration input may retain supported imports from react; Kudzu erases those references and never emits or executes React. New Kudzu source should import framework APIs from @kudzujs/core.

See the complete guide, interactive features, and current limits instead of relying on this README as an API reference.

Architecture

Kudzu treats React-shaped TSX as compiler input rather than as a browser runtime programming model:

React-shaped TypeScript/TSX
  -> ordered AST normalization passes
  -> state/effect/handler/binding/list analysis
  -> complete HTML + route-specific capability ESM
  • framework/compiler/normalization-pipeline.mjs owns pass order and repairs AST parent pointers after structurally changed transforms.
  • Focused passes own React, React Router, browser-signal, animation-frame, timer, render-control, and Worker validation.
  • The main transformer produces descriptors; effect and handler codegen modules turn them into route-specific ESM.
  • Unsupported nearby syntax fails with source-located diagnostics instead of falling back to React or a generic runtime.

Kudzu intentionally does not provide:

  • React runtime compatibility
  • Virtual DOM or hydration
  • Retained browser component instances
  • A default SPA router
  • Request-time SSR or server actions
  • A general client state or effect runtime

Browser code is a compiler-generated capability module, included only when a route uses that capability. Kudzu does not eliminate every runtime; it eliminates unused runtime.

Packages

Development

npm run check
npm test

Contributor instructions live in the repository.

License

MIT