{"id":11604,"library":"pusher-js","title":"Pusher Channels JavaScript Client","description":"The `pusher-js` library provides a robust client-side solution for real-time communication via Pusher Channels. It supports a wide array of JavaScript environments, including web browsers, React Native, Node.js, and web workers, offering a consistent API across platforms. Currently at stable version 8.5.0, the library demonstrates an active release cadence, frequently delivering security updates via dependency pinning and introducing new features like the `switchCluster` method for dynamic cluster changes without disrupting existing channel subscriptions. Its key differentiators include extensive platform compatibility, resilient fallback mechanisms (WebSockets, HTTP), and dedicated support for both public and private channels, including an optional build specifically for encrypted channels. It is designed purely for client-side interaction with the Pusher service, distinct from the `pusher-http-node` server-side library.","status":"active","version":"8.5.0","language":"javascript","source_language":"en","source_url":"https://github.com/pusher/pusher-js","tags":["javascript","pusher","client","websocket","http","fallback","isomorphic","events","pubsub"],"install":[{"cmd":"npm install pusher-js","lang":"bash","label":"npm"},{"cmd":"yarn add pusher-js","lang":"bash","label":"yarn"},{"cmd":"pnpm add pusher-js","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"Standard ES Module import for client-side usage. For CommonJS, use `require`.","wrong":"const Pusher = require('pusher-js');","symbol":"Pusher","correct":"import Pusher from 'pusher-js';"},{"note":"Use this specific path for encrypted channel support to include necessary encryption primitives.","wrong":"import Pusher from 'pusher-js';","symbol":"Pusher (with encryption)","correct":"import Pusher from 'pusher-js/with-encryption';"},{"note":"CommonJS `require` syntax for Node.js environments or older bundlers. For encrypted channels, use `require('pusher-js/with-encryption')`.","wrong":"import Pusher from 'pusher-js';","symbol":"Pusher (CommonJS)","correct":"const Pusher = require('pusher-js');"}],"quickstart":{"code":"import Pusher from 'pusher-js';\n\n// Replace with your actual Pusher app key and cluster\nconst PUSHER_APP_KEY = process.env.PUSHER_APP_KEY ?? 'YOUR_APP_KEY';\nconst PUSHER_APP_CLUSTER = process.env.PUSHER_APP_CLUSTER ?? 'eu'; // e.g., 'eu', 'us2'\n\nif (PUSHER_APP_KEY === 'YOUR_APP_KEY') {\n  console.warn('Pusher app key not set. Using a placeholder. Replace YOUR_APP_KEY and PUSHER_APP_CLUSTER with your actual credentials.');\n}\n\nconst pusher = new Pusher(PUSHER_APP_KEY, {\n  cluster: PUSHER_APP_CLUSTER,\n  forceTLS: true // Always use TLS for production\n});\n\npusher.connection.bind('connected', () => {\n  console.log('Pusher client connected!');\n});\n\npusher.connection.bind('disconnected', () => {\n  console.log('Pusher client disconnected!');\n});\n\nconst channel = pusher.subscribe('my-channel');\n\nchannel.bind('my-event', function(data: any) {\n  console.log('Received event on my-channel:', data);\n});\n\n// To simulate receiving an event (typically sent from a server):\n// setTimeout(() => {\n//   console.log('Simulating event trigger...');\n//   // This part would typically be handled by your server sending an event\n//   // For client-side simulation, you might use a debug API or similar.\n// }, 5000);\n\nconsole.log('Pusher client initialized and attempting to connect...');\n\n// You can switch cluster dynamically (since v8.5.0)\n// setTimeout(() => {\n//   console.log('Switching cluster to us2...');\n//   pusher.switchCluster('us2');\n// }, 10000);\n","lang":"typescript","description":"Demonstrates initializing a Pusher client, connecting, subscribing to a public channel, and binding to a custom event. Includes handling connection status."},"warnings":[{"fix":"Change your import statement from `import Pusher from 'pusher-js';` to `import Pusher from 'pusher-js/with-encryption';` (for ES Modules) or `const Pusher = require('pusher-js/with-encryption');` (for CommonJS).","message":"For encrypted channels, you must explicitly import from `pusher-js/with-encryption`. The default `pusher-js` import does not include the necessary encryption primitives to keep bundle sizes down.","severity":"gotcha","affected_versions":">=7.0.0"},{"fix":"Review and update your TypeScript definitions for custom authentication handlers to conform to the new discriminated union type. Refer to the official `pusher-js` documentation or source for the updated `AuthOptionsT` structure.","message":"The `AuthOptionsT` type was refactored to a discriminated union (`InternalAuthOptions | CustomAuthOptions`) in v8.5.0 for improved type safety. This might cause TypeScript compilation errors if you have custom authentication handlers or intricate type definitions related to `AuthOptionsT`.","severity":"breaking","affected_versions":">=8.5.0"},{"fix":"Upgrade to `pusher-js` version 8.5.0 or later to ensure all previous options, including custom handlers, are properly retained when `switchCluster` is invoked.","message":"Versions prior to 8.5.0 might not correctly persist custom options (like authentication handlers) when using the `switchCluster` method, which was introduced in 8.4.0-rc1. This could lead to unexpected behavior or disconnections upon cluster switching.","severity":"gotcha","affected_versions":"8.4.0-rc1 - 8.4.3"},{"fix":"It is highly recommended to upgrade to the latest stable version of `pusher-js` (8.5.0 or newer) to benefit from critical security patches and ensure your application is protected against known vulnerabilities.","message":"Multiple security vulnerabilities in transitive dependencies (e.g., `express`, `qs`, `lodash`, `node-forge`) were patched in versions 8.4.1 and 8.4.3. Older versions are susceptible to these known CVEs.","severity":"breaking","affected_versions":"<8.4.1, <8.4.3"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure you are importing from `pusher-js/with-encryption` for encrypted channel support, instead of the default `pusher-js` path.","cause":"Attempting to use encrypted channels without the correct import path.","error":"Module not found: Can't resolve 'pusher-js/with-encryption'"},{"fix":"Configure an authentication endpoint or a custom `userAuthentication` / `channelAuthorization` function in your Pusher client initialization options to authorize access to private/presence channels.","cause":"Attempting to subscribe to a `private-` or `presence-` channel without providing a `userAuthentication` or `channelAuthorization` callback in the Pusher client options.","error":"Pusher: Auth handler not provided for private/presence channel"},{"fix":"Double-check the `cluster` option when initializing Pusher (e.g., `'eu'`, `'us2'`, `'ap2'`) against your Pusher dashboard settings. Ensure it's a valid Pusher cluster.","cause":"Incorrect cluster name provided during Pusher client initialization, leading to an inability to resolve the WebSocket endpoint.","error":"Pusher: Unknown host: ws-mt1.pusher.com"},{"fix":"Verify your `appKey` and `cluster` are correct. Ensure `forceTLS: true` is set if your application is served over HTTPS. Check browser console for more specific WebSocket errors and network connectivity.","cause":"The WebSocket connection could not be established, often due to network issues, incorrect app key, invalid TLS settings (e.g., `forceTLS: false` with HTTPS origin), or firewall restrictions.","error":"Pusher: WebSocket connection failed: Event { isTrusted: true, type: 'error', ... }"}],"ecosystem":"npm"}