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

@vowel.to/client

v0.4.2

Published

Framework-agnostic voice agent library powered by Google Gemini Live API

Readme

@vowel.to/client

Add a voice agent to your web app with top-level apiKey/appId token-issuer identifiers, backend-issued tokens, and router-aware navigation.

npm version

⚠️ Beta Release — This open-source release is in beta. You may encounter rough edges, incomplete features, or breaking changes. We are actively reviewing and merging community PRs, but please expect some instability as we iterate toward a stable release. Your feedback and contributions are welcome.

SaaS coming soon — Currently requires the self-hosted Vowel stack. See github.com/usevowel/vowel/stack for setup instructions.

Links

Core features

  • Realtime voice — Gemini Live–compatible sessions with mic, playback, and tool use.
  • Router-aware adapters — Navigation and optional DOM automation so the agent can move through your app like a user.
  • Client-side actionsregisterAction() runs your app code when the model calls a tool (low latency, no server round-trip for business logic).
  • WebMCP (Web Model Context Protocol) — First-class bridge between vowel and the browser’s Model Context surfaces: expose your vowel actions as WebMCP tools, and discover tools the host page (or browser) already registered so the voice agent can call them. See WebMCP below.

Install

npm install @vowel.to/client

Quick start

import { Vowel, createNextJSAdapters } from '@vowel.to/client';
import { useRouter } from 'next/navigation';

const router = useRouter();

const { navigationAdapter, automationAdapter } = createNextJSAdapters(router, {
  routes: [
    { path: '/', description: 'Home page' },
    { path: '/products', description: 'Product catalog' },
    { path: '/cart', description: 'Shopping cart' },
  ],
  enableAutomation: true,
});

const vowel = new Vowel({
  apiKey: 'your-api-key',
  navigationAdapter,
  automationAdapter,
  language: 'en-US',
  initialGreetingPrompt:
    'Introduce yourself as a helpful assistant for this store and ask how you can help.',
});

vowel.registerAction(
  'searchProducts',
  {
    description: 'Search for products in the catalog',
    parameters: {
      query: { type: 'string', description: 'Search query in English' },
    },
  },
  async ({ query }) => {
    return { success: true, query };
  }
);

await vowel.startSession();

Register actions before calling startSession(). See Connection Paradigms for token flows and backend-issued tokens.

WebMCP (Web Model Context Protocol)

WebMCP is a core part of the client: the same registerAction tools your voice agent uses can participate in the browser’s WebMCP ecosystem, and tools registered elsewhere on the page can be pulled into the session as vowel actions.

  • enableExposure (default: true) — After you registerAction, vowel also registers that tool with navigator.modelContext.registerTool when the native WebMCP API is available, so MCP-compatible agents in the browser can invoke your app logic.
  • enableDiscovery (default: false) — On startup (and when you call rediscoverWebMCPTools()), vowel discovers tools from the host (testing API or a window.__webmcp_tools registry) and registers them as vowel actions the model can call over voice.

Native availability depends on the browser (experimental flags may apply); if WebMCP is not present, voice sessions and registerAction behave as usual—WebMCP is an additive layer.

import { Vowel, createNextJSAdapters } from '@vowel.to/client';
import { useRouter } from 'next/navigation';

const router = useRouter();
const { navigationAdapter, automationAdapter } = createNextJSAdapters(router, {
  routes: [
    { path: '/', description: 'Home page' },
    { path: '/settings', description: 'Account settings' },
  ],
  enableAutomation: true,
});

const vowel = new Vowel({
  apiKey: 'your-api-key',
  navigationAdapter,
  automationAdapter,
  language: 'en-US',
  initialGreetingPrompt:
    'You can use voice to navigate and run tools exposed via WebMCP on this page.',
  webMCP: {
    enableExposure: true, // expose registerAction tools to WebMCP (default)
    enableDiscovery: true, // ingest host WebMCP tools as vowel actions
  },
});

vowel.registerAction(
  'summarizePage',
  {
    description: 'Summarize the visible page for the user',
    parameters: {},
  },
  async () => ({ success: true, summary: '…' })
);

await vowel.startSession();

// After the host registers new WebMCP tools dynamically (e.g. route change):
await vowel.rediscoverWebMCPTools();

Session APIs

await vowel.startSession();
await vowel.pauseSession();
await vowel.resumeSession();

await vowel.sendText('What can I do on this page?');
await vowel.notifyEvent('Order placed successfully!', { orderId: '12345' });

const state = vowel.exportState({ maxTurns: 20 });
await vowel.startSession({ restoreState: state });

See Pause, Resume & State Restoration for details.

Web Component

CDN (no build step):

<script src="https://unpkg.com/@vowel.to/client/standalone/vowel-voice-widget.min.js"></script>

<vowel-voice-widget
  api-key="your-api-key"
  position="bottom-right">
</vowel-voice-widget>

Import (with build step):

import '@vowel.to/client/standalone';

// Then use in HTML or JSX
<vowel-voice-widget
  api-key="your-api-key"
  position="bottom-right">
</vowel-voice-widget>

Vanilla JS

CDN (no build step):

<script src="https://unpkg.com/@vowel.to/client/dist/client/index.mjs"></script>
<script type="module">
  const { Vowel, createControlledAdapters } = vowel;

  const { navigationAdapter, automationAdapter } = createControlledAdapters({
    enableAutomation: true,
  });

  const vowelClient = new Vowel({
    apiKey: 'your-api-key',
    navigationAdapter,
    automationAdapter,
    language: 'en-US',
    initialGreetingPrompt: 'Welcome! Ask me anything.',
  });

  document.getElementById('mic-button').addEventListener('click', () => {
    vowelClient.startSession();
  });
</script>

Import (with build step):

import { Vowel, createControlledAdapters } from '@vowel.to/client';

const { navigationAdapter, automationAdapter } = createControlledAdapters({
  enableAutomation: true,
});

const vowel = new Vowel({
  apiKey: 'your-api-key',
  navigationAdapter,
  automationAdapter,
  language: 'en-US',
  initialGreetingPrompt: 'Welcome! Ask me anything.',
});

vowel.startSession();

See Vanilla JS Integration for adapters and configuration.

Requirements

  • Node.js 18+ or Bun
  • A modern browser with microphone access
  • HTTPS for microphone access outside localhost

License

MIT. See LICENSE for details.