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

@userkit/react-mount

v0.7.0

Published

Draw UserKit's components in a React app that loads widget.js from the CDN: the page's React, none of ours, and the component bundle still fetched on demand.

Downloads

0

Readme

@userkit/react-mount

UserKit's components in a React app that loads the script from the CDN.

npm i @userkit/react-mount
import { Banner, OnboardingChecklist } from "@userkit/react-mount";

<OnboardingChecklist props={{ slot: "dashboard", onStepAction: go }} />
<Banner props={{ slot: "billing" }} />

The page keeps its <script src="https://cdn.userkit.dev/widget.js">. This package is the bridge, and nothing else — it draws no UI of its own.

Which package is this

Three ways to put a <Banner /> on a page, and they are not interchangeable:

| | React in your bundle | Components in your bundle | Needs a build | |---|---|---|---| | @userkit/react | yours | yes | yes | | widget.js alone | ours, a second copy | no — CDN, on demand | no | | this | yours | no — CDN, on demand | yes |

@userkit/react is the right answer for most apps: real components, your React, tree-shaken. Reach for this one when you have React and specifically want the components off the CDN — so the bundle does not grow, and a fix reaches the page without a redeploy.

It adds no runtime dependency. @userkit/js is a dependency for its types only; every import is import type and is erased at build, which a test in this package enforces rather than promises.

What it handles

  • When the script arrives. The tag is deferred and React does not wait for it, so the component draws its host element and mounts as soon as the loader announces itself. No polling window.UserKit on a timer.
  • Props that change. Handed over on every render whose values actually changed, as a re-render rather than a remount — a half-filled form survives it. No stringified key.
  • Callbacks. An inline arrow rebuilt each render is read fresh. No ref.
  • Leaving early. Unmounting before the component bundle has landed cancels the mount instead of stranding it in a node React already dropped.
  • A loader older than this package. Warns and leaves the page standing.

API

<UserKitMount name props className style id />

<UserKitMount name="PricingTable" props={{ onSelected: (price) => buy(price) }} />

name is any component @userkit/react exports — the same name you would write in data-userkit, so a page that later adopts a build renames nothing.

props is typed loosely, because this package deliberately does not depend on @userkit/react, where the prop types live. A project that has it as a devDependency can name them at the call site:

import type { SignInProps } from "@userkit/react";

<UserKitMount<SignInProps> name="SignIn" props={{ providers: ["google"] }} />

The per-component wrappers

One per name — <SignIn />, <Banner />, <NotificationBell />, … — taking the same props minus name.

useUserKitEmbed()

window.UserKit once it exists, null before and on the server. Use it for the imperative half:

const userkit = useUserKitEmbed();
<button onClick={() => userkit?.show()}>Suporte</button>;

What it does not do

The guards — SignedIn, SignedOut, SessionLoading, Verified, Flag — take over the page's own markup as DOM. Handing them children from React means two owners for the same nodes. In an app that has React, read the session and render the branch yourself.

Licence

MIT