System Overview
Mero.js is a thin composition of focused clients over a single fetch-based
transport. MeroJs is the entry point: it owns the HTTP transport, manages the
JWT token lifecycle, and exposes the specialised clients behind property
accessors. This page names the parts and says what each one does.
The shape of a client
Section titled “The shape of a client”import { MeroJs } from '@calimero-network/mero-js';
const sdk = new MeroJs({ baseUrl: 'http://localhost:2428' });await sdk.authenticate({ username: 'admin', password: 'pass' });
sdk.auth // AuthApiClient — login, tokens, key managementsdk.admin // AdminApiClient — contexts, apps, namespaces, groups, blobs, TEEsdk.rpc // RpcClient — execute WASM methods (lazy)sdk.events // SseClient — real-time events over SSE (lazy)sdk.ws // WsClient — WebSocket alternative (lazy, experimental)For the visual layer map, see Architecture at a glance on the home page.
The layers
Section titled “The layers”Layer 1 — Transport (HttpClient)
Section titled “Layer 1 — Transport (HttpClient)”A Web-Standards fetch wrapper (WebHttpClient). It attaches
Authorization: Bearer <token> to every request, combines caller abort signals
with an internal timeout, parses responses (JSON / text / blob / arrayBuffer),
and — crucially — handles token refresh: on a 401 with
x-auth-error: token_expired it refreshes once (single-flight) and retries the
original request. MeroJs builds this via createBrowserHttpClient, detecting
Tauri to default credentials: 'omit'.
You can also use the transport on its own — see the HTTP transport guide.
Layer 2 — API clients
Section titled “Layer 2 — API clients”Both wrap the shared HttpClient (constructor injection); neither manages
tokens itself — the transport’s hooks do.
AuthApiClient(sdk.auth) — direct HTTP to the node’s/authand identity endpoints: login (generateTokens),refreshToken, and root/client key management. See the auth API reference.AdminApiClient(sdk.admin) — the node’s/admin-apisurface: contexts, applications, packages, namespaces, groups, blobs, aliases, capabilities, metadata, upgrades/migration, and TEE. ~90 methods. See the admin API reference.RpcClient(sdk.rpc) — JSON-RPC over HTTP to/jsonrpc; executes WASM contract methods. See executing methods.
Layer 3 — Event streams
Section titled “Layer 3 — Event streams”SseClient(sdk.events) — Server-Sent Events from the node’s/sseendpoint. Reconnects automatically and re-subscribes on reconnect. Prefer this in production.WsClient(sdk.ws) — a WebSocket alternative with the same shape. Experimental; it logs a one-time console warning on first use.
Both are covered in the subscriptions guide.
Layer 4 — Token store
Section titled “Layer 4 — Token store”Where tokens are persisted between sessions. MemoryTokenStore (the default) is
ephemeral; LocalStorageTokenStore persists to localStorage. Implement the
TokenStore interface to back tokens with anything else.
Composition and token flow
Section titled “Composition and token flow”MeroJs creates one WebHttpClient and hands it to both AuthApiClient and
AdminApiClient. The transport is wired with hooks back into MeroJs’s token
state:
getAuthToken→ the current access token, attached as a bearer header.refreshToken→MeroJs.performTokenRefresh(), which is single-flight (in-process promise + amero-js:token-refreshWeb Lock + a re-read of the token store) because refresh tokens are single-use.onTokenRefresh→ persists the rotated token to the store.onAuthRevoked→MeroJs.clearToken()when the node reportstoken_reuse/token_revoked.
The full sequence is drawn in Authentication → token lifecycle.
Lazy initialisation
Section titled “Lazy initialisation”rpc, events, and ws are constructed on first access — there’s no cost if
you never touch them:
// Instantiated only when first accessed:sdk.rpc // RpcClient (lazy)sdk.events // SseClient (lazy)sdk.ws // WsClient (lazy, experimental — warns once)
// Always available:sdk.auth // AuthApiClientsdk.admin // AdminApiClientCall sdk.close() to shut down any open SSE/WS connections when you’re done.
Zero dependencies
Section titled “Zero dependencies”The SDK ships with no runtime dependencies. It’s built entirely on Web Platform
APIs. The HTTP and SSE surfaces run unchanged in the browser, Node 18+, Deno,
Bun, and edge workers; sdk.ws additionally needs a global WebSocket, which
is not present on Node before v22 (see the
runtime matrix):
| API | Used for |
|---|---|
fetch (incl. streaming response bodies) |
all HTTP requests, and the SSE client |
WebSocket |
the (experimental) WS client — global required (Node 22+) |
AbortController |
request cancellation & timeouts |
atob |
decoding the JWT payload to read exp |
localStorage |
optional token persistence (browser only) |
How it maps to the node
Section titled “How it maps to the node”Everything the SDK does is an HTTP call to a single merod node:
| Client | Node surface |
|---|---|
sdk.auth |
GET/POST /auth/*, /admin/keys* |
sdk.admin |
/admin-api/* (REST) |
sdk.rpc |
POST /jsonrpc (JSON-RPC) |
sdk.events |
GET /sse + POST /sse/subscription |
sdk.ws |
ws(s)://…/ws |
For what those endpoints mean at the protocol level, see the Calimero Core docs.