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

@hozo/vite

v0.2.0

Published

Vite integration for the Hozo compiler (Web lowering backend).

Readme

@hozo/vite

Vite integration for Hozo's Web backend. Lowers View/Text/Pressable/Button into semantic DOM and a real stylesheet, rewriting each component in place.

Setup

// vite.config.ts
import react from '@vitejs/plugin-react'
import { defineConfig } from 'vite'
import { hozo } from '@hozo/vite'

export default defineConfig({
  plugins: [hozo({ css: 'src/theme.css' }), react()],
})

hozo() must come before react(). The plugin runs at enforce: 'pre' so it sees the file as written — the JSX the compiler was built to read, not @vitejs/plugin-react's output.

Options

Every Hozo integration takes the same options.

| Option | Meaning | | --- | --- | | css | The project's Tailwind entry stylesheet. Read once per build by running Tailwind's own resolver. | | root | Project root. Defaults to Vite's. | | content | Which files the project-wide scan walks. | | sources | Modules whose primitives may be lowered. Defaults to @hozo/core and react-native. | | unloweredReactNativeJsx | Policy when Web output still contains JSX backed directly by React Native after lowering: 'allow' (default), 'warn', or 'error'. | | debug | Report what the scan found. |

css is the one worth setting. Left out, Hozo looks for the usual filenames and falls back to Tailwind's defaults if it finds none, reporting what it looked for. That fallback is right until the project defines its own tokens under a name Hozo did not guess — and then bg-brand compiles to a CSS variable nothing defines and p-4 to the wrong number of pixels, neither of which is an error.

Unlowered React Native JSX Policy

unloweredReactNativeJsx controls what happens when direct react-native JSX remains in Web output after Hozo lowering:

  • 'allow' (default): Leaves unlowered JSX in place to be resolved at bundle time by a compatibility layer (such as react-native-web). Adds zero overhead to the build.
  • 'warn': Emits a build warning listing any unlowered elements (e.g. SectionList), allowing progressive migration.
  • 'error': Fails the build if any direct React Native JSX survives lowering, naming the exact imported bindings that require fallback or lowering. Aliases and namespace JSX are tracked by the parser rather than guessed from source text.

The same switch decides whether Hozo rewrites React Native imports at all. Under 'allow', TouchableOpacity, TouchableWithoutFeedback, ActivityIndicator, Modal and Animated.View imported from react-native are left exactly as written. Under 'warn' and 'error' they lower to components from @hozo/rn-compat, and StyleSheet, Platform, Dimensions, Keyboard, AccessibilityInfo, PanResponder, useColorScheme and useWindowDimensions move there too. Those imports land in your source, so the application has to depend on @hozo/rn-compat; Hozo warns (RN_COMPAT_NOT_INSTALLED) when it cannot resolve it. Importing a component from @hozo/rn-compat yourself lowers it under any policy.

Two stylesheets

Each lowered module gets a <file>.hozo.css companion written next to it and imported normally, rather than served through a virtual module.

Alongside it, one project-wide stylesheet under node_modules/.hozo/ covers the classes the compiler couldn't read — a className that only a runtime expression produces. Those come from a byte scan of every source file rather than from the AST, so this plugin owns the project walk and the file-deletion signal while the cache in Rust owns scanning, staleness and persistence.

Dev mode

A style-only edit reaches the browser in two rounds: the .tsx change triggers the first, that transform writes the CSS, and the watcher seeing the new CSS triggers the second. It converges because identical bytes are never rewritten — without that, each transform would invalidate the stylesheet it had just written and the two would take turns forever.

The project-wide stylesheet lives under node_modules, which Vite's watcher ignores, so its invalidation is explicit rather than left to the watcher. Deleting a file drops its classes; creating one adds them, if the project's content globs would have included it.

MDX

A Hozo primitive written inline in an .mdx file compiles, on Astro as well as anywhere else.

That takes a step, because MDX does not hand this plugin JSX. Told jsx: true it produces JSX and everything works; told nothing it folds the document to automatic-runtime calls first — _jsx(View, { className: "p-4" }) — and Hozo reads JSX. @astrojs/mdx exposes no jsx option at all, so on Astro this was never a setting anybody forgot: the elements rendered, their class names passed through uncompiled, and only a project that also ran Tailwind over the same tree got rules for them. A Hozo-only project lost the styling with nothing reported at build or at run time.

So the calls are written back as JSX before the compiler reads them, and folded again at the end of the same transform — the step this plugin was already applying to its own output. They are folded back with the runtime they came from, which matters: Astro's MDX calls astro/jsx-runtime, and the same tree rebuilt by React's runtime renders as the string [object Object].

A call with no JSX spelling — a computed prop name, a spread child — is left folded rather than approximated, and named in a build warning. A fold's own output always has one, so in practice this is only reachable from a hand-written _jsx() call in an .mdx file's ESM block.


Part of Hozo, a Rust-powered universal UI compiler and accessibility-first layer for React Native. Most applications install @hozo/core and one build integration; see Getting started. Source and issues: github.com/iray-tno/hozo.