{"id":24083251,"url":"https://github.com/mitranim/webbs","last_synced_at":"2026-06-10T03:31:32.501Z","repository":{"id":65379297,"uuid":"71845547","full_name":"mitranim/webbs","owner":"mitranim","description":"Thin WebSocket adapter with auto-reconnect and offline buffering","archived":false,"fork":false,"pushed_at":"2018-06-09T07:54:53.000Z","size":37,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-24T06:44:40.087Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mitranim.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-10-25T00:58:04.000Z","updated_at":"2021-05-14T20:40:02.000Z","dependencies_parsed_at":"2023-01-20T08:45:46.382Z","dependency_job_id":null,"html_url":"https://github.com/mitranim/webbs","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitranim%2Fwebbs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitranim%2Fwebbs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitranim%2Fwebbs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitranim%2Fwebbs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mitranim","download_url":"https://codeload.github.com/mitranim/webbs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240959116,"owners_count":19884911,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-01-09T23:56:11.077Z","updated_at":"2026-06-10T03:31:32.245Z","avatar_url":"https://github.com/mitranim.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"## TOC\n\n* [Overview](#overview)\n* [Installation](#installation)\n* [API](#api)\n  * [`Webbs`](#webbs)\n    * [`.state`](#webbsstate)\n    * [`.open`](#webbsopenurl-protocol)\n    * [`.close`](#webbsclose)\n    * [`.send`](#webbssendmessage)\n    * [`.onEachOpen`](#webbsoneachopen)\n    * [`.onEachClose`](#webbsoneachclose)\n    * [`.onEachError`](#webbsoneacherror)\n    * [`.onEachMessage`](#webbsoneachmessage)\n    * [`.deinit`](#webbsdeinit)\n* [Changelog](#changelog)\n* [Misc](#misc)\n\n## Overview\n\nWebbs is a thin abstraction over the \u003ca href=\"https://developer.mozilla.org/en-US/docs/Web/API/WebSocket\" target=\"_blank\"\u003e `WebSocket` \u003c/a\u003e API available in modern browsers. It provides vital missing features: automatic reconnect with exponential backoff, and offline buffering of outgoing messages.\n\nSmall (≈ 180 LoC, 2.4 KiB minified), dependency-free, simple, hackable.\n\n## Installation\n\nWebbs is meant for a CommonJS-compatible bundler, such as \u003ca href=\"https://webpack.github.io\" target=\"_blank\"\u003eWebpack\u003c/a\u003e or \u003ca href=\"http://browserify.org/\" target=\"_blank\"\u003ebrowserify\u003c/a\u003e. Install it from \u003ca href=\"https://www.npmjs.com\" target=\"_blank\"\u003eNPM\u003c/a\u003e:\n\n```sh\nnpm i -E webbs\n# or\nyarn add -E webbs\n```\n\nThen import:\n\n```js\nimport {Webbs} from 'webbs'\n```\n\n## API\n\n### `Webbs()`\n\nCreates a new instance. It starts blank and inert. You must call `.open(url, protocol)` to actually open a connection.\n\n```js\nimport {Webbs} from 'webbs'\n\nconst webbs = new Webbs()\n\nwebbs.onEachOpen =\nwebbs.onEachClose =\nwebbs.onEachError =\nwebbs.onEachMessage =\nfunction report(event) {\n  console.info('Something happened:', event)\n}\n\nwebbs.open('ws://my-host:my-port', 'optional-protocol')\n```\n\n#### `webbs.state`\n\nAlways one of: `'CLOSED'`, `'CONNECTING'`, `'OPEN'`. Initially `'CLOSED'`.\n\n#### `webbs.open(url, protocol)`\n\nOpens the connection. Will automatically reconnect if disconnected. Stores `webbs.url` and `webbs.protocol` for automatic reconnects. Idempotent: has no effect if already connected.\n\n```js\nconst webbs = new Webbs()\nwebbs.open('ws://my-host:my-port', 'optional-protocol')\n```\n\n#### `webbs.close()`\n\nEmpties the outgoing message buffer, closes the connection, and doesn't reconnect. Can be reopened later. Will trigger `onEachClose` if the underlying websocket is open.\n\nAlso aliased as [`webbs.deinit`](#webbsdeinit).\n\n```js\nwebbs.close()\n// some time later\nwebbs.open(webbs.url, webbs.protocol)\n```\n\n#### `webbs.deinit()`\n\nSame as `.close()`. Aliased for compatibility with my other libraries, where `deinit` is the [dominant interface](https://mitranim.com/espo/#-isdeinitable-value-) for \"closing\" things.\n\n#### `webbs.send(message)`\n\nSends `message` over the websocket, if open. The message must be compatible with `WebSocket.prototype.send` (string or blob).\n\nIf not connected, adds `message` to `webbs.outgoingBuffer`. When connected, will send all buffered messages at once.\n\n```js\nconst webbs = new Webbs()\n\n// These get buffered\nwebbs.send('my msg')\nwebbs.send(new Blob([1, 2, 3]))\n\n// If this succeeds, the messages will be automatically sent\nwebbs.open('ws://my-host:my-port')\n```\n\n#### `webbs.onEachOpen`\n\nInitially `undefined`; you can assign a function. Gets called whenever an underlying native websocket successfully connects. May be triggered multiple times over the lifetime of the `webbs` instance.\n\n```js\nwebbs.onEachOpen = function report(event) {\n  console.info('Socket reconnected:', event)\n}\n```\n\n#### `webbs.onEachClose`\n\nInitially `undefined`; you can assign a function. Gets called whenever an underlying native websocket closes. May be triggered multiple times over the lifetime of the `webbs` instance.\n\nCounter-intuitively, this doesn't have symmetry with `.onEachOpen`. When reconnecting, `.onEachClose` will be called on each failed attempt.\n\nCalling `webbs.close()` or `webbs.deinit()` _always_ triggers `onEachClose`. If the underlying websocket was open, it's triggered asynchronously and receives the relevant DOM event. If the websocket wasn't open, it's triggered _synchronously_ and receives `undefined`.\n\n```js\nwebbs.onEachClose = function report(event) {\n  console.warn('Socket disconnected:', event)\n}\n```\n\n#### `webbs.onEachError`\n\nInitially `undefined`; you can assign a function. Gets called whenever an underlying native websocket fails to connect or loses an active connection. May be triggered multiple times over the lifetime of the `webbs` instance.\n\n```js\nwebbs.onEachError = function report(event) {\n  console.warn('Socket error:', event)\n}\n```\n\n#### `webbs.onEachMessage`\n\nInitially `undefined`; you can assign a function. Gets called whenever an underlying native websocket receives a message.\n\n```js\nwebbs.onEachMessage = function report(event) {\n  console.info('Socket message:', event)\n}\n```\n\n## Changelog\n\n### 0.0.9\n\nBetter minification. Slightly breaking.\n\n* use ES5-style class to avoid Babel garbage in the output\n* replaced `webbs.getState()` with the `webbs.state` getter\n* 2.6 KiB → 2.4 KiB\n\n### 0.0.8\n\nBreaking improvements and cleanup:\n\n* moved `url` and `protocol` arguments from constructor to `.open`\n* `.close` and `.deinit` are now equivalent\n* added `webbs.getState`\n* better ordering of state changes and callbacks; a webbs instance now reaches a consistent state before invoking the corresponding `onEach` callback\n* `onEachClose` is always called on `.close`, even if there was no underlying socket\n* removed `sendJson`; just define a function if you want\n\n## Misc\n\nI'm receptive to suggestions. If this library _almost_ satisfies you but needs changes, open an issue or chat me up. Contacts: https://mitranim.com/#contacts\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmitranim%2Fwebbs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmitranim%2Fwebbs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmitranim%2Fwebbs/lists"}