@mushi-mushi/web

Bug report and user feedback widget for the web. The bug mediator for AI-built apps: plain-English diagnosis + a ready fix, in your editor.
16,010 3
Install
npm install @mushi-mushi/web
Latest Version:1.33.1
License:MIT
Last Updated:Oct 22, 2026
Links: GitHub  ·  npm
Maintainer: kensaurus

@mushi-mushi/web

Your AI wrote it. Mushi tells you why it broke.

A bug widget for any website. When a user reports a problem, it sends a screenshot, the route, their note and the last console and network events to Mushi Mushi. Mushi explains the cause in plain English and hands your editor a fix. It renders in a Shadow DOM, so your CSS and the widget's never mix.

flowchart LR
    A["User taps the widget"] --> B["Mushi diagnoses the bug"] --> C["Fix lands in your editor"]

Quick start

npx mushi-mushi              # wizard: picks the right SDK, installs it, writes env vars
# or: npm install @mushi-mushi/web
import { Mushi } from '@mushi-mushi/web';

Mushi.init({
  projectId: '00000000-0000-0000-0000-000000000000', // from the console's Projects page
  apiKey: 'mushi_xxx',                               // report:write key from Setup → Verify
});

A launcher appears in the corner. That is the whole integration. On React, Vue, Svelte, Angular, React Native or Capacitor, use the framework package instead: react · vue · svelte · angular · react-native · capacitor.

What's inside

Report screen A free-text note, an optional type, a screenshot the reporter can mark up or remove. Reporters see your replies and fix status under Your reports.
Capture Screenshot, console, network, Web Vitals, and a timeline of routes and clicks before the report.
Offline Reports queue in IndexedDB and send when the connection is back. An on-device spam filter and rate limit run first.
Privacy A built-in PII scrubber, selector masking for screenshots, and opt-in session replay.
Stays out of the way Zero-size host with pointer-events: none, keyboard-first, respects reduced motion.
Runtime config Change the widget from the console without a deploy. Values you set in code win.
Size CI caps the core bundle at 89.5 KB gzipped (105 KB uncompressed). Screenshot markup and the Your reports views load only when used.

Recipes

Use your own button instead of the launcher. Other modes: auto, edge-tab, banner, manual, hidden (trigger modes).

const mushi = Mushi.init({
  projectId: 'proj_xxx',
  apiKey: 'mushi_xxx',
  widget: { trigger: 'attach', attachToSelector: '[data-mushi-feedback]' },
});
mushi.attachTo('#support-menu-feedback');

Ask for a report when users get stuck (rage clicks, long tasks, failing API calls). Session limits and cooldowns are always on.

Mushi.init({ projectId: 'proj_xxx', apiKey: 'mushi_xxx', proactive: { rageClick: true, longTask: true, apiCascade: true } });

Keep private data out of screenshots. Masked elements are painted over; blocked ones are removed.

Mushi.init({
  projectId: 'proj_xxx',
  apiKey: 'mushi_xxx',
  privacy: { maskSelectors: ['input'], blockSelectors: ['[data-payment]'], allowUserRemoveScreenshot: true },
});

Record a session replay of the moments before a report. Install rrweb in your app and pass your own import, so your bundler can split it into a lazy chunk (coexisting with Sentry Replay).

Mushi.init({ projectId: 'proj_xxx', apiKey: 'mushi_xxx', capture: { replay: 'rrweb', rrweb: () => import('rrweb') } });

Send through your own domain so ad blockers don't drop reports. Your proxy must allow only your host, project and /v1/ paths.

Mushi.init({ projectId: 'proj_xxx', apiKey: 'mushi_xxx', tunnel: '/api/mushi-tunnel', ignoreErrors: ['ResizeObserver loop'] });

Tag users and report caught errors. Breadcrumbs, tags and any active Sentry scope are attached for you.

const mushi = Mushi.init({ projectId: 'proj_xxx', apiKey: 'mushi_xxx' });
mushi.identify('usr_42', { email: 'aya@example.com', segment: 'beta' });

try {
  await runCheckout();
} catch (err) {
  mushi.captureException(err, { severity: 'high', tags: { surface: 'checkout' } });
}

Track product events for funnels and paths in the same console. Do Not Track and Global Privacy Control are respected.

const mushi = Mushi.init({ projectId: 'proj_xxx', apiKey: 'mushi_xxx', analytics: { consent: 'required' } });
mushi.setConsent('granted');
mushi.track('checkout_started', { plan: 'pro' });

Check the install. Safe to call before Mushi.init(); reports endpoint, CSP and widget health.

const health = await Mushi.diagnose(); // { apiEndpointReachable, cspAllowsEndpoint, widgetMounted, widgetHostPointerSafe, ... }

Name the current screen for the "what happened before" timeline.

const mushi = Mushi.init({ /* ... */ });
mushi.setScreen({ name: 'Chat', route: '/chat', feature: 'roleplay' });

Match your brand. The widget uses your page's font and light/dark colors. Override any token in CSS (all tokens):

#mushi-mushi-widget { --mushi-accent: #b8860b; --mushi-accent-fg: #000; --mushi-font: Georgia, serif; }

Screenshots cannot capture cross-origin iframes or tainted <canvas> elements, and strict CSP can block them. Playwright and jsdom helpers live in @mushi-mushi/web/test-utils, which production bundles never load.

Learn more

Web SDK reference · Runtime config · Presets · Analytics · Rewards and replies

License

MIT

Related Packages

@mushi-mushi/cli

Mushi CLI: SDK setup, MCP wiring, bug triage. The bug mediator for AI-built apps...

10,380 3
mushi-mushi

One command adds a bug report widget to any app. The bug mediator for AI-built a...

6,112 3
@mushi-mushi/vue

Vue 3 SDK for Mushi Mushi — plugin, composables, error handler integration

3,157 3
create-mushi-mushi

Run `npm create mushi-mushi` to add the Mushi Mushi bug-reporting SDK to your ex...

5,326 3
@veryai/widget

Cross-framework widget for Very palm verification.

20,956

Version History

Version Released License
1.33.1 MIT
1.33.0 MIT
1.32.3 MIT
1.32.2 MIT
1.32.1 MIT