vscode-jsonrpc

A lightweight JSON-RPC messaging library that carries requests, responses, and notifications between a client and a server over streams, sockets, or IPC.

Library
npm
v9.0.3
1,792 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
92 /100 Excellent
Development Activity 88
Maintenance 92
Community 88
Maturity 60
Momentum 40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
78 /100 Good
Architecture 88
Code Quality 78
Innovation 72
Learning Curve 75

vscode-jsonrpc is the base messaging layer underneath the Language Server Protocol: it implements the JSON-RPC 2.0 wire format and connection lifecycle used to talk between a VSCode language client and a language server, but it works standalone for any process-to-process JSON-RPC channel, not just LSP. A MessageConnection wraps a pair of readers/writers (stdio pipes, sockets, or in Node’s case a child process’s stdout/stdin) and exposes typed request/notification registration, cancellation, and progress reporting on top of raw message framing.

The package ships three entry points — vscode-jsonrpc/node for Node.js process/stream transports, vscode-jsonrpc/browser for Worker-based transports, and a common core shared by both — so the same connection API works whether the two ends are a spawned child process, a Web Worker, or a browser-hosted worker. It is the transport vscode-languageserver and vscode-languageclient (its sibling packages in this same monorepo) are built on, and is also usable directly by anyone building a custom RPC channel between two Node or browser processes.

What You Get

  • A MessageConnection API for registering typed request and notification handlers and sending/receiving JSON-RPC messages
  • StreamMessageReader/StreamMessageWriter for Node.js stream-based transports (stdio, sockets, child process pipes)
  • Cooperative cancellation via CancellationTokenSource, including a shared-array-buffer-backed cancellation strategy for cross-thread cancellation without an extra message round-trip
  • Content-length message framing and encoding/decoding hooks (ContentEncoder/ContentDecoder) for custom compression or transformation of the wire format
  • Separate /node and /browser entry points so the same connection API runs unmodified in a Node.js process or a Web Worker
  • Progress notification support ($/progress) and built-in request cancellation ($/cancelRequest) matching the LSP base protocol

Common Use Cases

  • Implementing the transport layer for a custom Language Server Protocol server or client outside of the higher-level vscode-languageserver/vscode-languageclient packages
  • Building a JSON-RPC channel between a VSCode extension’s main process and a spawned child process or worker
  • Adding request cancellation and progress reporting to an existing stdio-based tool without hand-rolling message framing
  • Bridging a Node.js host process and a browser-hosted extension host over a Web Worker using the shared /browser API
  • Any general-purpose process-to-process RPC channel that needs typed requests/notifications rather than a bespoke ad hoc protocol

Under The Hood

Architecture The package splits into a common core (connection.ts, messages.ts, messageReader.ts, messageWriter.ts, cancellation.ts, linkedMap.ts) and two thin runtime layers, node and browser, that each supply a RAL (runtime abstraction layer) implementation for their environment. createMessageConnection in connection.ts is the central abstraction: it takes any MessageReader/MessageWriter pair, tracks pending requests in a LinkedMap, and dispatches to registered request/notification handlers, with $/cancelRequest and $/progress handled directly inside the connection rather than left to a layer above it. Cancellation has an alternate path — sharedArrayCancellation.ts — that lets a request be cancelled by flipping a byte in a SharedArrayBuffer instead of sending a message, which only makes sense because the transport boundary is already abstracted behind MessageReader/MessageWriter. Swapping node/main.ts for browser/main.ts changes nothing in connection.ts itself, which is the point of the split.

Tech Stack TypeScript throughout, targeting Node.js >=14, compiled via project-referenced tsc -b builds (tsconfig.json/tsconfig.publish.json/tsconfig.watch.json per package) rather than a bundler for the npm output. Browser tests are bundled with webpack and executed against a real browser via Playwright (runBrowserTests.js); the Node test suite runs directly under Mocha. The monorepo’s own tooling (build/bin/all.js) drives per-package compile/lint/test across all six published packages from one root npm run all. Linting is centralized through a shared eslint.config.base.js extended per package, using typescript-eslint and a Microsoft-authored stylistic plugin.

Code Quality Tests exist for both the common protocol logic (general.test.ts, linkedMap.test.ts) and the Node transport (a separate node/test suite), split so the same common-layer tests can also run against the browser transport — but the test surface is comparatively thin relative to the package’s role as a dependency for the entire LSP ecosystem; there’s no visible coverage reporting. Error handling is typed: ResponseError/ErrorCodes model JSON-RPC error responses explicitly rather than throwing bare exceptions, and public APIs are fully typed generics (RequestType0 through RequestType9) rather than any-typed parameter lists. Naming and file layout are consistent across the common/node/browser split, and every source file carries the same Microsoft copyright/license header, suggesting enforced formatting conventions even without a public style guide.

API Design The request/notification API is fully generic over parameter and return types (RequestType0..9, NotificationType0..9), so consumers get compile-time checking of request signatures instead of stringly-typed dispatch — a deliberate ergonomics choice given this package underlies a protocol (LSP) with hundreds of distinct request/notification shapes. Getting started requires minimal boilerplate: wrap a reader/writer pair, call connection.listen(), and register typed handlers, mirrored identically on both client and server sides. Progress and cancellation are exposed as first-class connection methods rather than something each protocol built on top has to reimplement, which keeps downstream packages like vscode-languageserver and vscode-languageclient thin.

Used by 31 apps in this directory

Go
49%
MIT

Bytebase

Devops

14,512

An open-source database CI/CD and DevSecOps platform — schema migration review, GitOps-driven changes, data masking, and access control across MySQL, PostgreSQL, Oracle, Snowflake, MongoDB, and more.

View details
92
Repo Health
73
Technical
68
Dependency
Built with
Go 49%
TypeScript 42%
Updated 4 days ago
JavaScript
90%
Other

CodeSandbox

Code Editors · Developer Tools

13,650

Instantly ready browser-based IDE that runs full npm dependency resolution and transpilation entirely client-side, with no server needed.

View details
67
Repo Health
76
Technical
62
Dependency
Built with
JavaScript 90%
Updated 3 weeks ago
TypeScript
84%
Apache 2.0

Continue

AI Code Assistants · AI Development · Automation

36,049

Open-source coding agent for VS Code, JetBrains, and CLI with support for 30+ LLM providers.

View details
73
Repo Health
88
Technical
62
Dependency
Built with
TypeScript 84%
Updated 5 days ago
TypeScript
98%
Other

Kibana

Analytics · Monitoring

21,301

Your open source window into the Elastic Stack — query, visualize, and act on data stored in Elasticsearch with real-time dashboards, AI-assisted search, and automated alerting.

View details
98
Repo Health
87
Technical
63
Dependency
Built with
TypeScript 98%
Updated 4 days ago
TypeScript
97%
MIT

likec4

Developer Tools · Devops

5,756

Define your software architecture as code and get always up-to-date, interactive C4 diagrams generated automatically from a DSL.

View details
89
Repo Health
83
Technical
77
Dependency
Built with
TypeScript 97%
Updated 5 days ago
TypeScript
97%
MIT

likec4

Developer Tools · Devops

5,756

Define your software architecture as code and get always up-to-date, interactive C4 diagrams generated automatically from a DSL.

View details
89
Repo Health
83
Technical
77
Dependency
Built with
TypeScript 97%
Updated 5 days ago
TypeScript
97%
MIT

likec4

Developer Tools · Devops

5,756

Define your software architecture as code and get always up-to-date, interactive C4 diagrams generated automatically from a DSL.

View details
89
Repo Health
83
Technical
77
Dependency
Built with
TypeScript 97%
Updated 5 days ago
TypeScript
97%
MIT

likec4

Developer Tools · Devops

5,756

Define your software architecture as code and get always up-to-date, interactive C4 diagrams generated automatically from a DSL.

View details
89
Repo Health
83
Technical
77
Dependency
Built with
TypeScript 97%
Updated 5 days ago
TypeScript
97%
MIT

likec4

Developer Tools · Devops

5,756

Define your software architecture as code and get always up-to-date, interactive C4 diagrams generated automatically from a DSL.

View details
89
Repo Health
83
Technical
77
Dependency
Built with
TypeScript 97%
Updated 5 days ago

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers