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

@dentsdumidi/chmln

v0.1.0

Published

Embeddable product feedback widget that turns user wishes into safe UI previews.

Downloads

109

Readme

Chameleon

Chameleon helps users show what they expected your product to do.

Instead of vague feedback like "this is confusing" or "I wish this worked differently", users chat with an embeddable widget and shape a safe preview of the missing flow, behavior, or UI they had in mind.

Chameleon does not edit the real app or run model-generated code. It clones the page, applies structured preview operations, and sends the product team the prompt, page context, chat history, and final scenario.

What It Does

  • captures safe page context from the current page
  • lets users chat with an AI model about what they expected
  • keeps conversation state per feedback journey
  • renders a temporary preview using structured operations
  • exports a report for product review

Supported preview operations:

  • setText
  • setStyle
  • insertAfter
  • insertBefore
  • replace
  • remove

Chameleon can update existing page elements and safely insert common preview primitives:

  • button
  • select
  • input
  • textarea
  • checkbox
  • radio
  • link
  • image
  • text
  • badge
  • list
  • card
  • section
  • form
  • modal
  • table
  • tabs
  • toolbar

No raw HTML. No generated JavaScript. No production DOM mutation.

Docker

docker compose up --build

Dashboard: http://localhost:8080 Demo: http://localhost:8080/demo/

For the local demo-only OpenAI path:

CHAMELEON_OPENAI_API_KEY=sk-... docker compose up --build

The local direct-OpenAI demo keeps response state in memory per journey. It resets on refresh or rebuild.

Hosted Backend

The hosted MVP lives in supabase/.

import { createCloudProposalGenerator, createCloudReportSubmitter, mountChameleon } from "@dentsdumidi/chmln";

const cloud = {
  functionsUrl: "https://PROJECT.supabase.co/functions/v1",
  projectId: "PROJECT_ID",
  anonKey: "SUPABASE_ANON_KEY"
};

mountChameleon({
  generateProposal: createCloudProposalGenerator(cloud),
  onSubmit: createCloudReportSubmitter(cloud)
});

Deploy the Supabase functions with OPENAI_API_KEY set server-side. Hosted proposal generation stores the last OpenAI response id per widget journey and continues from it on the next turn.

Local SDK

npm install @dentsdumidi/chmln
import { createOpenAIProposalGenerator, mountChameleon } from "@dentsdumidi/chmln";

mountChameleon({
  generateProposal: createOpenAIProposalGenerator({
    apiKey: "demo-openai-api-key"
  }),
  onSubmit(report) {
    console.log(report);
  }
});

Do not put a private LLM provider key in a public page. Use the hosted/backend path for production.

Browser CDN

The browser entry exposes window.Chameleon:

<script type="module">
  import "https://esm.sh/@dentsdumidi/chmln/browser";

  window.Chameleon.init({
    projectId: "PROJECT_ID",
    endpoint: "https://PROJECT.supabase.co/functions/v1/chameleon-propose"
  });
</script>

init is for proposal generation. Wire report submission through onSubmit or the hosted helpers from the npm package.

Package

The npm package publishes:

  • @dentsdumidi/chmln: ESM SDK with TypeScript declarations
  • @dentsdumidi/chmln/browser: browser/CDN entry that attaches window.Chameleon

Before publishing, verify the package from Docker:

npm run docker:pack

The full chameleon package name is already taken on npm, so this package uses @dentsdumidi/chmln.

React bindings are intentionally not included in the first package. The core Web Component API is the stable surface; a React wrapper can be added as a thin package after the core API settles.

Core Shape

The model returns structured scenario JSON:

{
  "title": "Add dropdown next to action",
  "summary": "User expected an adjacent dropdown for extra actions.",
  "chatResponse": "I kept the original button and added a dropdown next to it. What still feels off?",
  "scenarioType": "ui_improvement",
  "components": [
    {
      "type": "pagePreview",
      "operations": [
        {
          "type": "setStyle",
          "target": { "role": "button", "text": "Vague action" },
          "styles": [{ "property": "background-color", "value": "red" }]
        },
        {
          "type": "insertAfter",
          "target": { "role": "button", "text": "Vague action" },
          "node": {
            "type": "select",
            "label": "More actions",
            "options": ["Option 1", "Option 2"],
            "styles": [{ "property": "margin-left", "value": "8px" }]
          }
        }
      ]
    }
  ],
  "acceptanceCriteria": ["The original button remains visible.", "The dropdown appears to its right."]
}

This keeps feedback visual and reviewable while staying safe for customer websites.

Trying Real Pages

Arbitrary production websites often block console-injected scripts with CSP. For real-page testing, use a Chrome extension content script. For customer adoption, use first-party install through the script/npm SDK so the host app intentionally allows Chameleon.