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

@rohansguliani/mux-chat-ui

v0.4.6

Published

Mux's own chat as Solid pieces an app lays out itself (transcript, composer, model and reasoning pickers, a ready-made panel), built from Mux and talking to the app's @rohansguliani/mux-chat-runtime mount.

Readme

@rohansguliani/mux-chat-ui

Mux's own chat as pieces you lay out in your app: the conversation, the composer, the model and reasoning menus, and a ready-made panel. They are Mux's actual components (built from the Mux commit the runtime package pins), styled from their own stylesheet, scoped so they never restyle your page.

Your server mounts one route with @rohansguliani/mux-chat-runtime: app.all("/api/mux/*", (c) => mux.handle(c.req.raw, { subject: userID })).

import { createMuxChat, MuxChat, MuxTranscript, MuxComposer, MuxModelPicker } from "@rohansguliani/mux-chat-ui"
import "@rohansguliani/mux-chat-ui/style.css"

const chat = createMuxChat({
  storageKey: "todos",
  onToolResult: ({ readOnly }) => { if (!readOnly) refreshTodos() },
})

<MuxChat chat={chat} colorScheme="dark" tokens={{ "background-base": "#0f1114", "text-interactive-base": "#8ab4ff" }}>
  <header class="my-header">Assistant <MuxModelPicker /> <button onClick={() => chat.newChat()}>New chat</button></header>
  <MuxTranscript empty={<MyStarterPrompts onPick={(text) => chat.send(text)} />} />
  <MuxComposer placeholder="Ask about your todos…" pickers={false} />
</MuxChat>

chat.send("Summarize my week")   // e.g. from a button elsewhere in your app

| Piece | | | --- | --- | | createMuxChat(options) | the signed-in user's chat: grant (renewed before it expires), their last chat or a new one, send, newChat, retry, focus, dispose | | <MuxChat chat colorScheme tokens class style> | the root the pieces sit in; your own elements can sit in it too | | <MuxTranscript empty> | the conversation, with its loading, failed, and ended states | | <MuxComposer placeholder pickers> | the composer, or the assistant's open question or permission request | | <MuxModelPicker>, <MuxReasoningPicker> | the menus, wherever you want them | | <MuxChatPanel title subtitle placeholder suggestions> | a ready-made layout of all of the above | | mountMuxChat(element, options) | the ready-made panel for apps not written in Solid |

createMuxChat options: url (where mux.handle is mounted, default /api/mux), storageKey, sessionTitle, preferredModel (provider/model until the user picks one), toolLabels (default: each tool's label), and onToolResult (a tool call finished while the chat was open; readOnly: false means it may have changed app data).

Styling. tokens sets Mux's theme values (names without --), e.g. background-base, background-stronger, surface-raised-base, text-strong, text-base, text-weak, border-weak-base, text-interactive-base, font-family-sans. Your own CSS can target the pieces' data-component/data-action attributes too; Mux's rules sit in cascade layers (mux-*), so unlayered app rules win. Every Mux rule is scoped to the pieces' root (the build fails otherwise), and menus render in an overlay root that carries the same theme.

Bundling. solid-js is a peer dependency (one Solid for the app and the pieces). The markdown and diff workers are ES-module workers: with Vite, set worker: { format: "es" }. Code highlighting, math, and diagrams load on demand.

Testing your app

@rohansguliani/mux-chat-ui/testing gives app tests stable hooks, so they never depend on the chat's markup:

import { chatSelectors, readChat, replyFinished } from "@rohansguliani/mux-chat-ui/testing"

await page.locator(`#assistant ${chatSelectors.input}`).fill("Add NVDA to Tech")
await page.keyboard.press("Enter")
await page.waitForFunction(replyFinished, await page.$("#assistant"))
const { replies, tools, sessionID } = await page.locator("#assistant").evaluate(readChat)

To pin a model in tests, set ${storageKey}:model in localStorage to provider/model before starting a new chat.