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

@faiwer/react

v19.0.4

Published

A hobby project. A naive and simplified React implementation

Readme

What is it?

A naive React implementation. Why? What's wrong with the existing one? Nothing. I just wanted to implement it from scratch by myself. It can be used as a drop-in replacement for some simple React apps. May require some trivial changes, though.

A few stats:

  • ~5.5k LoC in TypeScript
  • ~122 KiB: transpiled JS code
  • ~44 KiB: minified by terser
  • ~16 KiB: minified gzipped
    • preact is about ~10 KiB

It supports

  • JSX
  • Functional components
  • Class components (limited)
  • Hooks:
    • useState
    • useRef
    • useMemo, useCallback
    • useStableCallback (a better version of useEffectEvent)
    • useLayoutEffect, useEffect (improved versions)
    • useId
    • useContext
  • Refs
  • Context
  • Portals
  • Fragments
  • Hot Module Replacement
  • Preact Dev Tools (partially)

Installation

  • npm uninstall react react-dom @types/react @types/react-dom
  • npm i --save react@npm:@faiwer/react
  • npm i --save --force react-dom@npm:@faiwer/react-dom
  • You might need to update your tsconfig.json (no necessarily):
    "compilerOptions": {
      "jsx": "react-jsx",
    }
    Or use "jsx": "preserve"
  • If you're using eslint-plugin-react than configure this in your .eslintrc:
    "settings": {
      "react": { "version": "19" } // not 'detect'
    },
  • Good luck. If your project is big enough, I'm pretty sure you got a ton of type errors. Sorry :-)

Usage

To mount an app:

const container = document.getElementById('root');
createRoot(container).render(<App />);

To show your app in the Preact DevTools:

import { preactDevTools } from 'react/debug';
// …
createRoot(container).render(
  <App />,
  import.meta.env.DEV ? { preactDevTools } : undefined

The 2nd argument also supports:

{
  // If `true` the lib will make more checks and add the `__fiber` field for each
  // generated DOM Node to simplify debugging
  testMode: boolean,
  // A hook to improve local error stack traces. Provide a method that converts
  // __filename into an internal URL that your DevTools can handle.
  // E.g., this worked out for Vite:
  transformSource: source => ({
    ...source,
    fileName: source.fileName.replace(/^.+\/src/, location.origin),
  }),
  // And this worked out for Webpack:
  transformSource: source => ({
    ...source,
    fileName: source.fileName.replace(
      /^.+\/src/,
      'webpack://your-project-package-name/src'
    ),
  }),

TODO

  • JSX: Math namespace
  • <Lazy/>
  • Make all hooks pure
  • Resolve "TODO: add a test" comments
  • leverage isStaticChildren in jsx()

It does NOT support

… and probably never will:

  • Class Components: getSnapshotBeforeUpdate
  • Synthetic events
  • Portals:
    • Event bubbling from portals
    • Rendering multiple portals in the same DOM node
  • memo (because components are memoized by default)
  • Some less popular tools
    • useInsertionEffect
    • useOptimistic (could be polyfilled)
    • useDeferredValue (could be polyfilled)
    • useDebugValue (dev tools are not supported)
    • <StrictMode/>.
    • <Profiler/>.
    • preconnect, prefetchDNS, preinit, preinitModule, preload, preloadModule
  • Modern stuff:
    • useTransition, startTransition
    • <Suspense/>, lazy.
  • Form-based hooks (like useActionState, useFormStatus)
  • React Dev Tools. Just take a look at __REACT_DEVTOOLS_GLOBAL_HOOK__, it's huge. E.g., it has reactDevtoolsAgent, a class with 20-30 methods…
  • flushSync (not supported by the engine)
  • SSR

Major differences

  • It renders HTML-comment for nullable nodes and some fragments. Why? It helps a lot to keep the reconciliation algorithm simple. Took this idea from Angular.
  • No synthetic events. I don't see any reason to implement them.
  • All components are memoized by default. Why not?
  • Not too much custom DOM-related code. This library is supposed to be simple and silly. Whereas React-DOM lib is huge.
  • No modern fiber-driven stuff like <Suspense>, cacheSignal, or use. Too much work. It took React many years to cook it well :)