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

@convai/web-widget

v0.1.3

Published

Two-line script-tag embed for the Convai chat widget. A <convai-widget> custom element with a closed shadow root and a lazily loaded runtime.

Readme

@convai/web-widget

Add a Convai character to any website with one custom element and one script tag.

Quickstart

Paste this, replace two values, and you have a working widget. It puts your API key in the page, which is fine on your own machine and not fine in productionstep two moves it to your server.

<convai-widget character-id="YOUR_CHARACTER_ID" api-key="YOUR_API_KEY"></convai-widget>
<script src="https://cdn.jsdelivr.net/npm/@convai/[email protected]/v1.js" async></script>

A launcher bubble appears in the bottom-right corner. Click it: the runtime downloads, the panel opens, and you can talk to your character by text or by voice.

React

The script tag goes in your HTML shell; the element is ordinary JSX.

<!-- index.html -->
<script src="https://cdn.jsdelivr.net/npm/@convai/[email protected]/v1.js" async></script>
<convai-widget character-id={CHARACTER_ID} api-key={API_KEY} />

In Next.js, use next/script with strategy="afterInteractive" — it injects a classic script tag, which is what the loader needs.

Do not import this package into an app bundle. The loader derives the runtime chunk's URL from its own <script src>, so a bundled import (or a <script type="module">) leaves it with nothing to derive from: the bubble paints and then fails on click with could not resolve the runtime URL. Load it from a script tag. The npm package exists so you can self-host v1.js and runtime.js from your own origin.

Before you ship

api-key is visible to anyone who views source, never expires, and is scoped to your whole account — the widget logs a one-time warning saying so. Replace it with token-endpoint, a single route you host whose entire job is to relay one call:

app.post('/api/convai-token', async (req, res) => {
  const upstream = await fetch('https://api.convai.com/user/connect', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json', 'CONVAI-API-KEY': process.env.CONVAI_API_KEY },
    body: '{}',
  })
  res.status(upstream.status).json(await upstream.json())
})

Then swap one attribute:

- <convai-widget character-id="YOUR_CHARACTER_ID" api-key="YOUR_API_KEY"></convai-widget>
+ <convai-widget character-id="YOUR_CHARACTER_ID" token-endpoint="/api/convai-token"></convai-widget>

The widget mints on first engagement and reuses the token for about an hour, so this runs once per hour of use, not once per conversation. token-endpoint outranks api-key, so leaving both on during a migration is safe — but delete the key anyway, it is still in your page source.

A third mode, connect-endpoint, proxies the full connect request for teams who want to inspect or gate it server-side. All three are covered in the docs.

If your character has Long-Term Memory enabled, add end-user-id — the connect request is rejected without it. Each distinct value consumes an account resource, so read the guidance before pointing it at production traffic.

Why it is built this way

  • The script tag costs 8 KB. It paints the launcher immediately and nothing else. The full SDK — around 230 KB gzipped — is fetched only when a visitor actually engages, so a page nobody talks to pays almost nothing.
  • Your CSS and the widget's cannot collide. Everything renders inside a closed shadow root, so the host page cannot reach in and the widget cannot leak out. Theming happens through eight documented custom properties.
  • Your API key stays on your server once you move to token-endpoint.

Documentation

https://docs.convai.com/embed

Authentication in depth with working Express, Next.js and Cloudflare Worker recipes; the complete attribute and event reference; a React and Next.js usage guide; theming and ::part() hooks; CSP requirements; and guidance on end-user-id and Long-Term Memory.

Versioning

0.1.3 is a stable release: npm install @convai/web-widget and jsDelivr's unversioned URL both resolve it. Pin the exact version anyway for reproducible deploys —

<script src="https://cdn.jsdelivr.net/npm/@convai/[email protected]/v1.js" async></script>
npm install @convai/[email protected]   # only needed to self-host the two files

This package is early, and it bundles a prerelease of @convai/web-sdk. The bundle is self-contained, so you install nothing from that — but expect the surface to move before 1.0.

Browser support

Any browser with custom elements and shadow DOM: Chrome, Edge, Firefox, and Safari 16.4+. The widget needs microphone access for voice mode; text chat works without it.