Deno-first TypeScript SDK for NNRP/1 Preview4, with Node-compatible ESM packages and a browser WASM client.
The SDK separates application roles from carrier providers. Native client and server packages own role/session lifecycle; each native carrier package owns its Rust transport implementation and platform libraries; the browser client owns the browser WASM runtime.
| Package | Owned boundary |
|---|---|
@nnrp/core |
Runtime-neutral contracts, codecs, validation, endpoints, and provider selection. |
@nnrp/native-client |
Node.js/Deno client, session, control, object, and cache lifecycle. |
@nnrp/native-server |
Node.js/Deno listener, accepted session, response, control, object, and cache APIs. |
@nnrp/browser-client |
Browser client/session lifecycle and the single nnrp-wasm-browser artifact. |
@nnrp/transport-tcp |
TCP provider behavior and TCP native libraries. |
@nnrp/transport-quic |
QUIC provider behavior and QUIC native libraries. |
@nnrp/transport-ipc |
Unix-domain socket / Windows named-pipe provider behavior and native libraries. |
@nnrp/transport-websocket |
Native WebSocket provider libraries plus the browser host-WebSocket binding. |
| Build mode | Role packages | Runtime target | Carrier packages |
|---|---|---|---|
core |
@nnrp/core |
Runtime-neutral TypeScript | None |
backend-native |
@nnrp/native-client, @nnrp/native-server |
Node.js 20.11+ and Deno 2+ | TCP, QUIC, IPC, and WebSocket packages |
browser-client |
@nnrp/browser-client |
Modern ES2022 browser with WASM | @nnrp/transport-websocket |
Install exactly the carriers an application permits. One installed provider is used directly; multiple providers are probed and selected by the frozen policy, limits, cost, preference, throughput, and RTT rules.
npm install @nnrp/native-client @nnrp/transport-tcpimport {
createTokenSubmitRequest,
NNRP_DEFAULT_SUBMIT_HEADER,
NNRP_DEFAULT_SUBMIT_POLICY,
NNRP_STANDARD_PROFILE_TOKEN,
NNRP_TOKEN_DELTA_SCHEMA_ID,
NNRP_TOKEN_DELTA_SCHEMA_VERSION,
} from "@nnrp/core";
import { openNativeClient } from "@nnrp/native-client";
import { createTcpTransportProvider } from "@nnrp/transport-tcp";
const client = await openNativeClient({
endpoint: "nnrp://127.0.0.1:4433/session/default",
transports: [createTcpTransportProvider()],
transportPolicy: "auto",
});
const session = await client.openSession({
profileId: NNRP_STANDARD_PROFILE_TOKEN,
schemaId: NNRP_TOKEN_DELTA_SCHEMA_ID,
schemaVersion: NNRP_TOKEN_DELTA_SCHEMA_VERSION,
});
const result = await session.submit(createTokenSubmitRequest({
identity: { operationId: 1n, frameId: 1, header: NNRP_DEFAULT_SUBMIT_HEADER },
policy: NNRP_DEFAULT_SUBMIT_POLICY,
chunks: [{ payload: new Uint8Array([1, 2, 3]) }],
}));
await session.close();
await client.close();Use @nnrp/native-server for a listener and @nnrp/browser-client with @nnrp/transport-websocket for a browser
client. The JavaScript quick start covers all
three roles.
Role APIs receive an NNRP application endpoint such as nnrp://host:4433/session/default. Carrier-local locators and
role-specific security live in providerRoutes, keyed by transport kind. A native client adopts one eligible route; a
native server opens every eligible Auto/Prefer route as one atomic listener set. TCP and QUIC can derive locators, while
IPC (unix://, npipe://) and WebSocket (ws://, wss://) accept explicit carrier locators. Provider-local addresses
are never serialized into operation payloads.
Native and browser clients expose the same submit, cancellation, deadline, priority, progress, partial-result, runtime
object, cache reference, and event polling concepts. @nnrp/native-server additionally exposes listen/accept and
server-only response controls. Public methods use structured Preview4 metadata and bigint for wire u64 fields;
native handles, WASM handles, and transport-library handles remain private. Session open and resume are asynchronous,
and resumable sessions expose runtime-issued tickets through session.recoveryTicket() for
client.resumeSession(ticket).
deno task wire-conformance:native
deno task wire-conformance:browser
deno task installed-package-smoke
deno task benchmark:conformance --plan scripts/release-benchmark-plan.json --output artifacts/release-benchmark-results.jsonWire evidence is written beneath artifacts/wire-conformance/native and artifacts/wire-conformance/browser. Release
tarball evidence, including Node, Deno, and browser import results, is written to
artifacts/installed-package-smoke/evidence.json. Benchmark results are checked against the committed Preview3
coarse-FFI baseline and the public result is recorded in
doc/benchmarks/preview4-runtime-and-carriers.md.
nnrp-js uses Deno for repository tooling and keeps Node.js compatibility for package consumers. Bun is not a supported
runtime, build tool, compatibility target, or CI axis for this SDK.
| Example | Purpose |
|---|---|
examples/native-client.ts |
Node/Deno native client shape for CLI and agent callers. |
examples/native-server-adapter.ts |
Native server/adapter lifecycle shape. |
examples/browser-client.ts |
Browser/edge WASM client shape. |
examples/opencode-agent-client.ts |
Native client sketch for coding-agent style integrations. |
Examples use package entrypoint names through the repository import map. They are checked with
deno task examples:check.
Preview package versions are synchronized across the role, transport, and core packages. Source package manifests stay
private: true for workspace safety; the release workflow stages publishable manifests before running npm publish.
The release workflow uses npm Trusted Publishing with GitHub OIDC. Configure trusted publishers for all npm packages
with repository NagareWorks/nnrp-js, workflow release.yml, and GitHub environment npm; no NPM_TOKEN secret is
required for the default path. A release selects one canonical npm dist-tag. Each new package version receives that tag
through npm publish --tag, and the workflow verifies the tag across the complete package set only after every version
exists. Trusted Publishing does not authorize post-publish npm dist-tag mutations, so reruns fail explicitly rather
than falling back to a long-lived token when an existing version has a different tag.
TCP, QUIC, IPC, and WebSocket transport packages each bundle their own supported native platform artifacts. Role packages contain no native libraries. The browser client is the only package carrying browser WASM; the WebSocket package does not duplicate it.
The avatar wall above is updated automatically from the repository contributor list.
GitHub README rendering does not support per-avatar dynamic tooltips for an auto-generated contributor wall, so use the linked contributors graph if you want individual profile pages and account IDs.