Smee Client
Smee Client is a JavaScript/TypeScript library that provides a local proxy for webhooks received by the smee.io service, enabling developers to test webhook integrations without deploying their applications to a publicly accessible server. It listens for incoming webhook payloads on a designated smee.io channel and forwards them to a specified local HTTP endpoint. The current stable version is 5.0.0, released in November 2025, which introduced a breaking change making the `start()` method asynchronous. The project maintains an active release cadence, with several minor and patch updates preceding the major version bump, indicating ongoing development and support. A key differentiator for Smee Client is its straightforward integration with the smee.io platform, offering a simple and effective solution for local development and debugging of applications that rely on external webhook events, such as GitHub App development or payment gateway notifications, by tunneling public internet requests directly to a developer's machine.
Common errors
-
TypeError: smee.start is not a function
cause Attempting to call `smee.start()` without `await` in an asynchronous context after v5.0.0.fixChange the calling code to `await smee.start();`. Ensure the surrounding function is `async`. -
Error: Missing URL / Error: Invalid Smee URL
cause The `source` option provided to `new SmeeClient()` is either missing, an empty string, or not a valid `https://smee.io/your-channel` format.fixVerify that the `source` property is a complete and valid Smee.io channel URL, including the protocol and a unique path. Obtain a fresh URL from https://smee.io/ if unsure.
Warnings
- breaking The `Client#start()` method is now an asynchronous function and must be awaited. Previously, it was synchronous.
- gotcha Features such as connection timeout, `startForward`/`stopForward` methods, and the `query-forwarding` option, which were introduced in versions like `v4.2.0` and `v4.4.0`, were subsequently reverted in `v4.4.2`. Users upgrading from `v4.2.0` or `v4.4.0` might find these functionalities unexpectedly removed in later `v4.x` releases.
Install
-
npm install smee-client -
yarn add smee-client -
pnpm add smee-client
Imports
- SmeeClient
const SmeeClient = require('smee-client')import { SmeeClient } from 'smee-client' - SmeeClient
import type { SmeeClientOptions } from 'smee-client' - SmeeClient
import SmeeClient from 'smee-client'
import { Client as SmeeClient } from 'smee-client'
Quickstart
import { SmeeClient } from 'smee-client';
async function runSmeeClient() {
// Replace with your unique smee.io URL, e.g., from https://smee.io/
// It's highly recommended to set this via an environment variable.
const smeeUrl = process.env.SMEE_URL || 'https://smee.io/your-unique-channel-id';
if (smeeUrl === 'https://smee.io/your-unique-channel-id') {
console.warn('Warning: Using a placeholder Smee URL. Please set SMEE_URL environment variable or update the code.');
console.warn('Get your unique channel URL from https://smee.io/.');
}
const smee = new SmeeClient({
source: smeeUrl,
target: 'http://localhost:3000/webhook', // Your local development server endpoint
logger: console,
});
console.log(`Forwarding webhooks from ${smeeUrl} to http://localhost:3000/webhook`);
try {
// Client#start() is now an async function since v5.0.0
const events = await smee.start();
console.log('Smee client started. Waiting for events...');
events.on('message', (message) => {
console.log('Received webhook message:', message.url);
// message contains 'headers', 'body', 'url', 'query', etc.
});
events.on('error', (error) => {
console.error('Smee client encountered an error:', error);
});
events.on('close', () => {
console.log('Smee client connection closed.');
});
// Example: Stop the client after a minute (optional)
// setTimeout(() => {
// events.close();
// console.log('Smee client stopped after 1 minute.');
// }, 60 * 1000);
} catch (error) {
console.error('Failed to start Smee client:', error);
}
}
runSmeeClient();