{"id":"ec529b1f7329accb","repo":"websockets/ws","slug":"ws-does-not-work-in-the-browser-browser-clients-m","errorCode":null,"errorMessage":"ws does not work in the browser. Browser clients must use the native WebSocket object","messagePattern":"ws does not work in the browser\\. Browser clients must use the native WebSocket object","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"browser.js","lineNumber":4,"sourceCode":"'use strict';\n\nmodule.exports = function () {\n  throw new Error(\n    'ws does not work in the browser. Browser clients must use the native ' +\n      'WebSocket object'\n  );\n};\n","sourceCodeStart":1,"sourceCodeEnd":9,"githubUrl":"https://github.com/websockets/ws/blob/ae1de54330cef77e487548890fabfeb9aae1d83d/browser.js#L1-L9","documentation":"This error is thrown synchronously whenever the 'ws' module is imported in a browser bundle. The package.json declares a 'browser' field (and an exports.browser condition) that maps to browser.js, whose sole export is a function that throws this Error. Bundlers like webpack and vite resolve this stub automatically when the build target is a browser, replacing the full Node.js implementation. The library does this deliberately because ws depends on Node core modules (net, http, crypto) that cannot run in a browser environment.","triggerScenarios":"A bundler (webpack/vite/rollup/esbuild) with a browser target resolves the 'browser' field in ws's package.json and substitutes browser.js for index.js. The throw fires the moment any code does `require('ws')` or `import ... from 'ws'` in the browser build. It also fires if a developer explicitly imports 'ws/browser.js'.","commonSituations":"A developer copies Node.js WebSocket client code into a frontend React/Vue/Angular project without switching to the browser-native WebSocket. A shared/isomorphic module unconditionally requires 'ws' and is bundled for the browser. A bundler misconfiguration where the 'browser' field resolves but no fallback shim is provided. Migrating a server-rendered app to client-side rendering.","solutions":["Replace `new WebSocket(...)` from ws with the browser-native `new WebSocket(url)` in any code that runs in the browser.","If the module must be isomorphic, guard the import behind an environment check (typeof window !== 'undefined') and only require ws on the server side.","Configure your bundler to alias 'ws' to a stub or to the native WebSocket only for browser builds, and keep the real ws for server builds.","If you genuinely need ws in a browser-like environment (e.g. jsdom/electron renderer), ensure the bundler does not resolve the 'browser' condition — force Node resolution for that entry point."],"exampleFix":"// before (shared module, breaks in browser)\nconst WebSocket = require('ws');\nconst ws = new WebSocket('ws://example.com');\n\n// after (isomorphic — use native in browser, ws on server)\nconst WebSocket =\n  typeof window !== 'undefined'\n    ? window.WebSocket\n    : require('ws');\nconst ws = new WebSocket('ws://example.com');","handlingStrategy":"validation","validationCode":"// Detect a browser environment before importing ws\nconst isBrowser =\n  typeof window !== 'undefined' && typeof window.WebSocket !== 'undefined';\n\nif (isBrowser) {\n  throw new Error(\n    'Use the native browser WebSocket (window.WebSocket) instead of the ws package.'\n  );\n}","typeGuard":"// Type guard for the browser-native WebSocket constructor\nfunction isBrowserWebSocket(Ctor) {\n  return typeof Ctor === 'function' && Ctor.prototype && 'readyState' in Ctor.prototype;\n}","tryCatchPattern":"// Rarely useful: catching the throw from requiring ws in a browser bundle\nlet WebSocketImpl;\ntry {\n  WebSocketImpl = require('ws');\n} catch (err) {\n  if (typeof window !== 'undefined') {\n    WebSocketImpl = window.WebSocket;\n  } else {\n    throw err;\n  }\n}","preventionTips":["Never import 'ws' unconditionally in code that runs in a browser bundle — use environment guards or separate entry points.","Configure your bundler (webpack resolve.fallback, vite resolve.alias) to exclude 'ws' for browser builds.","In isomorphic libraries, export a factory that picks the native WebSocket in browsers and ws on the server.","Review package.json 'browser' fields of dependencies when building for the browser."],"tags":["browser","bundler","websocket","environment","isomorphic"],"analyzedSha":"ae1de54330cef77e487548890fabfeb9aae1d83d","analyzedAt":"2026-08-03T19:11:18.437Z","schemaVersion":2}