Library / SDK
sockjs/sockjs-client avatar
sockjs/sockjs-client

sockjs-client: a WebSocket-like API for browsers that block WebSockets

WebSocket emulation - Javascript client

8,501 stars1,271 forksJavaScriptMIT

At a glance

What is it?
sockjs-client is a browser JavaScript library that presents a WebSocket-shaped object and falls back to other transports when a native WebSocket cannot be established. The API is familiar; the cost is a required SockJS server counterpart and a release line that has been quiet since 2022.
Who is it for?
Adopt sockjs-client when you control the server side and your users sit behind proxies or old browsers that break native WebSockets, and when you accept that the last published release is v1.6.1 from 2022-05-28 and that package.json is already at 1.6.2. Do not adopt it for a greenfield stack where a plain WebSocket plus your own reconnect logic is enough, and do not expect it to fix a server that cannot hold long-lived connections.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 6 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem sockjs-client solves: WebSockets that never open

The README states the intent plainly: SockJS is a browser JavaScript library that provides a WebSocket-like object, and it is intended to work in environments which do not support the WebSocket protocol, for example behind restrictive corporate proxies. That is the whole case for the library. You write code against an object that looks like WebSocket, and the library decides how the bytes actually travel.

The audience is narrower than the download numbers suggest. If your users are on modern browsers on ordinary networks, a native WebSocket almost always connects, and sockjs-client adds a negotiation layer you do not need. The library earns its place in two situations: corporate networks where an upgrade request is stripped or blocked, and applications that must still run on browsers old enough to lack a usable WebSocket implementation. The README also notes the API should follow the HTML5 WebSockets API as closely as possible, so migration cost in application code is low. The cost moves to the server.

How the transport negotiation actually works

The README describes the order of operations: under the hood SockJS tries to use native WebSockets first, and if that fails it can use a variety of browser-specific transport protocols, presented through WebSocket-like abstractions. The constructor is where you influence that decision.

The options hash documented in the README takes server, transports and sessionId. transports accepts a string or an array of strings, and the README says it exists because sometimes it is useful to disable some fallback transports. That is the lever you pull when a proxy mangles one transport but not another. server is a string appended to the URL for the actual data connection, defaulting to a random 4 digit number; sessionId is a number or a function, and when given a number the library generates session ids of that length using its random string generator. Both client and server use session identifiers to distinguish connections, which is why the README also mentions cookie-based sticky sessions: streaming transports should support cookies so a load balancer can pin a connection to one backend.

The package.json browser field is worth reading before you bundle. It remaps ./lib/transport/driver/websocket.js to ./lib/transport/browser/websocket.js, eventsource to ./lib/transport/browser/eventsource.js, ./lib/transport/driver/xhr.js to ./lib/transport/browser/abstract-xhr.js, crypto to ./lib/utils/browser-crypto.js, and events to ./lib/event/emitter.js. Those substitutions are why the library behaves differently in a bundler than in Node, and they are the first place to look when a build resolves the wrong transport module.

Installing sockjs-client and opening a first connection

The README's Getting Started section loads the library from a CDN in an HTML head element. The package.json declares jsdelivr as dist/sockjs.min.js, so that path is the published browser build. Pinning the version in the URL is what the README's own example does.

html
<script src="https://cdn.jsdelivr.net/npm/sockjs-client@1/dist/sockjs.min.js"></script>

If you install from npm instead, the package name is sockjs-client and package.json requires Node >=12. The related searches around "sockjs client npm" and "sockjs client cdn" map to these two paths.

bash
npm install sockjs-client

Once the script is loaded, the README gives this example. The constructor takes the server URL, and the handlers mirror WebSocket: onopen, onmessage, onclose. Note that e.data is what onmessage receives, exactly as with a native WebSocket message event.

javascript
var sock = new SockJS('https://mydomain.com/my_prefix');
sock.onopen = function() {
    console.log('open');
    sock.send('test');
};

sock.onmessage = function(e) {
    console.log('message', e.data);
    sock.close();
};

sock.onclose = function() {
    console.log('close');
};

The URL must point at a SockJS server, not at an arbitrary HTTP endpoint. The README is explicit that SockJS-client does require a server counterpart and points to SockJS-node for Node.js. If you stand this up against a plain HTTP server, the connection will not open, and the failure will look like a transport problem rather than a missing server.

The server counterpart is not optional, and that is the real constraint

This is the limitation that decides most adoption questions. sockjs-client is half of a protocol. The README lists the other halves: SockJS-node for Node.js, SockJS-erlang, SockJS-cyclone, SockJS-tornado, SockJS-twisted, SockJS-aiohttp, the Spring Framework client and server, vert.x, Xitrum, the Atmosphere Framework, and Actix SockJS for Rust. There is also a work-in-progress list that includes SockJS-go, SockJS-perl and others.

That breadth looks generous until you have to pick one and keep it current. The client is a browser library; the server is where sessions, sticky routing and transport support actually live. If your backend is a framework with no SockJS server implementation, the client is useless to you. The README does not document rollback behaviour, nor does it describe what happens when a transport degrades mid-session; the material covers transport selection at connection time, not graceful renegotiation afterwards.

There is also a version-skew trap. The most recent release listed is v1.6.1 from 2022-05-28, while package.json declares version 1.6.2. The last push to the default branch was on 2026-09-10, so the repository is not archived and work has happened since the release, but the published npm artifact and the repository state are not the same thing. Verify which version your install resolves to before you reason about behaviour.

sockjs-client vs a plain WebSocket, and where STOMP fits

The honest alternative is the native WebSocket API. It is one object, no negotiation, no server counterpart beyond whatever speaks the protocol, and it is what sockjs-client tries to use first anyway. The difference in approach is what happens on failure: a native WebSocket either connects or fires an error, and your code handles that; sockjs-client intercepts the failure and retries over a different transport. If you are willing to write that fallback yourself, or if your users never hit the failure case, the library is overhead.

The second comparison is STOMP. Several related searches pair sockjs-client with Stompjs, and the split is clean: STOMP is a messaging protocol with frames, destinations and subscriptions, while sockjs-client is a transport that carries bytes. They are commonly used together, with SockJS providing the connection and STOMP providing the message semantics on top. Choosing sockjs-client does not give you pub/sub; choosing STOMP does not give you proxy fallback. If you need subscriptions and acknowledgements, you need both, and you should confirm that your chosen server supports the pairing before you build on it.

Bundler and framework friction worth knowing about

One related search phrase, "sockjs client global is not defined", points at a class of problem that the package.json browser field explains. The library ships separate driver modules for Node and for browsers, and the browser field rewrites the imports at bundle time. A bundler that ignores or misapplies that field can pull in a Node-oriented module, and the resulting error surfaces as a missing global rather than as a transport failure.

The framework searches (Angular, React, TypeScript) all reduce to the same two questions: does the bundler honour the browser field, and are there type definitions. The README does not document TypeScript types, and the repository's top-level entries do not include a types directory; the related search for Types/sockjs-client suggests people look for them separately. Treat typing as something you verify in your own setup rather than something the project promises. The same applies to the CDN path: the README's example pins @1, which will track the 1.x line rather than a specific patch.

Maintenance, licence and upgrade cost

The repository is not archived and the last push to main was on 2026-09-10. The release history tells a slower story: v1.6.1 on 2022-05-28, v1.6.0 on 2022-02-27, v1.5.2 on 2021-08-24. Published releases have not moved in years even though the branch has. For an adopter, that means the npm artifact you install is stable and old, and any fix landed after v1.6.1 is only in the repository until a release is cut. Plan for that gap: either pin to v1.6.1 and accept it, or build from the repository and own that build.

The licence is MIT, stated in the repository metadata and present as a LICENSE file at the top level. MIT is permissive and imposes no copyleft obligation on your application; it does require that the copyright notice and permission notice travel with copies or substantial portions of the software. That is a description of the licence text, not legal advice, and your own distribution model decides what compliance looks like.

Upgrade cost is dominated by the dependency chain rather than the client itself. package.json pulls debug ^3.2.7, eventsource ^2.0.2, faye-websocket ^0.11.4, inherits ^2.0.4 and url-parse ^1.5.10. Each of those has its own release cadence, and the browser field means some of them are swapped out in browser builds. The README also points to a Tidelift subscription for commercial support and maintenance. If you need a support contract, that is the documented route; the mailing list and the Gitter channel are the community routes.

Editorial conclusion

Adopt sockjs-client when you control the server side and your users sit behind proxies or old browsers that break native WebSockets, and when you accept that the last published release is v1.6.1 from 2022-05-28 and that package.json is already at 1.6.2. Do not adopt it for a greenfield stack where a plain WebSocket plus your own reconnect logic is enough, and do not expect it to fix a server that cannot hold long-lived connections. Before committing, confirm which server implementation you will run (sockjs-node, the Spring Framework fallback, or one of the other ports the README lists), verify that your proxy does not buffer the streaming transport, and check whether the transport you rely on is still reachable in your target browsers.

Frequently asked questions

What is the purpose of WebSocket?

The README does not define the protocol's purpose directly; it describes SockJS as providing a WebSocket-like object and following the HTML5 WebSockets API as closely as possible. The library's own purpose is to keep a low latency, full duplex, cross-domain channel working in environments that do not support the WebSocket protocol.

What is sockjs-client?

It is a browser JavaScript library that provides a WebSocket-like object. Under the hood it tries native WebSockets first and falls back to other browser-specific transports, presenting them through WebSocket-like abstractions.

Are WebSockets outdated?

The README gives no position on that. It presents native WebSockets as the first transport SockJS tries, with fallback transports used only when that fails, and states that SockJS is intended to work in environments which do not support the WebSocket protocol.

What are the downsides of using WebSockets?

The README does not enumerate WebSocket downsides. The closest statement is that restrictive corporate proxies can prevent the protocol from working, which is the reason SockJS exists and why it falls back to polling and streaming transports.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. Releases
  5. sockjs/sockjs-client on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/sockjs-sockjs-client.svg)](https://hysenlabs.com/projects/sockjs-sockjs-client)