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

@gtmi/webchat

v0.3.0

Published

Drop-in webchat widget powered by RAMP. Includes React components for the browser and framework-agnostic server-side proxy handlers.

Readme

@gtmi/webchat

Drop-in webchat widget powered by RAMP. Includes React components for the browser and framework-agnostic server-side proxy handlers.

Authentication

This is a private package. You need an npm token with read access to the @gtmi scope.

Generate a token: log into npmjs.com → Avatar → Access Tokens → Generate New Token → Granular Access Token → Packages: Read-only on @gtmi scope.

Local development (recommended)

Add the token to your user-level ~/.npmrc. This is a one-time setup — npm automatically loads it for every project on your machine:

@gtmi:registry=https://registry.npmjs.org/
//registry.npmjs.org/:_authToken=npm_YOUR_TOKEN_HERE

No project-level .npmrc needed. Just npm install @gtmi/webchat from any project and it works.

Never commit .npmrc files containing tokens. If you use a project-level .npmrc instead, add it to .gitignore.

CI / Vercel deployment

Store your token as an environment variable (NPM_TOKEN) in your CI provider or Vercel project settings, then generate .npmrc at build time.

Vercel: Add a prebuild script to your package.json:

{
  "scripts": {
    "prebuild": "echo '//registry.npmjs.org/:_authToken=${NPM_TOKEN}' > .npmrc"
  }
}

Then set NPM_TOKEN in your Vercel project's Environment Variables (Settings → Environment Variables).

Other CI (GitHub Actions, etc.): Write the .npmrc before npm install:

- run: echo '//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}' > .npmrc
- run: npm install

Install

npm install @gtmi/webchat
# or
pnpm add @gtmi/webchat
# or
yarn add @gtmi/webchat

Peer dependencies

Install the following peer dependencies alongside @gtmi/webchat:

npm install @twilio-paste/core @twilio-paste/icons @twilio/conversations @twilio/voice-sdk react react-dom

Minimum versions:

| Package | Minimum version | |---------|----------------| | @twilio-paste/core | >=21 | | @twilio-paste/icons | >=13 | | @twilio/conversations | >=2 | | @twilio/voice-sdk | >=2 | | react | >=18 | | react-dom | >=18 |

Quick start

1. Set up environment variables

Your server needs two environment variables to configure the proxy:

| Variable | Example | Description | |----------|---------|-------------| | AGENT_SERVER_URL | https://ramp-agent-e80bbf4e12e1.herokuapp.com | Full URL of the RAMP agent server | | API_SERVER_URL | https://ramp-api-a37d85642e1b.herokuapp.com | Full URL of the RAMP API server |

Add these to your .env.local (Next.js) or equivalent:

AGENT_SERVER_URL=https://ramp-agent-e80bbf4e12e1.herokuapp.com
API_SERVER_URL=https://ramp-api-a37d85642e1b.herokuapp.com

Use the full URL with https:// protocol. No trailing slash or path segments.

2. Set up the server proxy

The proxy sits between your user's browser and the RAMP servers so you don't need to worry about CORS. It uses the Web standard Request/Response API and works in Next.js App Router, Vercel Edge, Cloudflare Workers, Deno, Bun, and any runtime that supports the Fetch API.

Next.js App Router (recommended)

Create a catch-all API route:

// app/api/webchat/[...path]/route.ts
import { createWebchatProxy } from '@gtmi/webchat/proxy'

export const { GET, POST } = createWebchatProxy({
  agentServerUrl: process.env.AGENT_SERVER_URL!,
  apiServerUrl: process.env.API_SERVER_URL!,
})

That's it -- one file, three lines of code.

Other frameworks

createWebchatProxy returns { GET, POST } handlers that accept a standard Request and return a Response. Adapt to your framework's routing convention:

// Express / Node.js example
import { createWebchatProxy } from '@gtmi/webchat/proxy'

const proxy = createWebchatProxy({
  agentServerUrl: process.env.AGENT_SERVER_URL!,
  apiServerUrl: process.env.API_SERVER_URL!,
})

app.all('/api/webchat/*', async (req, res) => {
  const handler = req.method === 'GET' ? proxy.GET : proxy.POST
  const response = await handler(
    new Request(`https://localhost${req.originalUrl}`, {
      method: req.method,
      headers: { 'Content-Type': 'application/json' },
      body: req.method !== 'GET' ? JSON.stringify(req.body) : undefined,
    })
  )
  res.status(response.status).json(await response.json())
})

3. Add the widget to your app

Wrap your app (or the page) in a Twilio Paste Theme.Provider, then render the WebchatWidget:

'use client'

import { useState } from 'react'
import { Theme } from '@twilio-paste/core/theme'
import { Button } from '@twilio-paste/core'
import { WebchatWidget } from '@gtmi/webchat'

export default function ChatPage() {
  const [triggerCount, setTriggerCount] = useState(0)

  return (
    <Theme.Provider theme="default">
      <Button variant="primary" onClick={() => setTriggerCount((c) => c + 1)}>
        Open Webchat
      </Button>
      {triggerCount > 0 && (
        <WebchatWidget
          triggerCount={triggerCount}
          countryCode="US"
        />
      )}
    </Theme.Provider>
  )
}

Auto-open on page load

To open the webchat immediately when the page loads, initialize triggerCount to 1:

const [triggerCount, setTriggerCount] = useState(1)

Loading a specific template

Pass an objectID to load a specific RAMP template's UI config (colors, greeting, avatar, etc.) instead of the default:

<WebchatWidget
  triggerCount={triggerCount}
  countryCode="US"
  objectID="[email protected] Template (Master)"
/>

The objectID is the template identifier from RAMP. You can find it in the RAMP dashboard URL or configuration.

Widget props

| Prop | Type | Required | Default | Description | |------|------|----------|---------|-------------| | triggerCount | number | Yes | -- | Increment to open the webchat. The widget appears when > 0. | | countryCode | string | No | 'US' | Country code for agent phone number resolution (e.g. 'US', 'UK', 'DE'). | | objectID | string | No | -- | RAMP template ID. When set, fetches that template's UI config. | | demoNumber | string | No | -- | Twilio phone number to display in the widget. | | voiceTokenUrl | string | No | -- | URL to fetch a Twilio Voice token. When set, a call button appears in the webchat. | | uiConfig | object | No | -- | Override UI configuration (colors, greeting text, etc.). | | liveAgentConfig | object | No | -- | Live agent handoff configuration. | | rightOffsetPx | number | No | -- | Override CSS right offset for the webchat panel. |

Package exports

| Export | Description | |--------|-------------| | @gtmi/webchat | React components (WebchatWidget, WebchatModal, etc.) | | @gtmi/webchat/shared | Shared types and utilities | | @gtmi/webchat/proxy | Server-side proxy (createWebchatProxy) |

How it works

Browser (React components)
    |
    v
Your server (/api/webchat/*)  <-- proxy from this package
    |
    v
RAMP servers (agent + API)

The proxy routes requests to the correct RAMP server based on the path. No API keys are required -- the RAMP routes are public. The proxy exists to avoid CORS issues by making server-to-server requests on behalf of the browser.