Skip to content

Quickstart

Mero.js is the JavaScript SDK for a Calimero node. This page gets you from an empty project to a live call: install, create a client, authenticate, list contexts, and execute a WASM method.

Terminal window
npm install @calimero-network/mero-js

Requires Node.js 18+ or any modern browser. Zero runtime dependencies — the SDK is built on the Fetch API (including streaming responses for SSE), WebSocket, and AbortController. (sdk.ws needs a global WebSocket, which on Node requires v22+.)

  1. Create an SDK instance. Point it at your node’s URL.

    import { MeroJs } from '@calimero-network/mero-js';
    const sdk = new MeroJs({
    baseUrl: 'http://localhost:2428',
    timeoutMs: 10_000, // optional, default 10s
    });
  2. Authenticate. Exchange a username and password for a JWT access + refresh token pair. The tokens are held in memory and attached to every subsequent request.

    await sdk.authenticate({
    username: 'admin',
    password: 'your-password',
    });
    console.log(sdk.isAuthenticated()); // true
  3. List contexts through the admin API.

    const res = await sdk.admin.getContexts();
    console.log(res.contexts); // ContextWithGroup[]
  4. Execute a WASM method over JSON-RPC. execute<T> returns the decoded return value directly.

    const value = await sdk.rpc.execute<{ value: string }>({
    contextId: 'ctx-id-here',
    method: 'get_value',
    argsJson: { key: 'hello' },
    });
    console.log(value);
  5. Clean up. Close any open SSE/WebSocket connections when you’re done (e.g. on unmount or process exit).

    sdk.close();

By default tokens live in memory and are lost on page reload. Pass a tokenStore to persist and restore them automatically:

import { MeroJs, LocalStorageTokenStore } from '@calimero-network/mero-js';
const sdk = new MeroJs({
baseUrl: 'http://localhost:2428',
tokenStore: new LocalStorageTokenStore('my-app-tokens'),
});
// On the next page load, tokens are restored from localStorage.
// sdk.isAuthenticated() is true if a valid token pair exists.

Every failure mode maps to a typed error. The three you’ll see most:

import { HTTPError, RpcError } from '@calimero-network/mero-js';
try {
const result = await sdk.rpc.execute({
contextId: 'ctx-id',
method: 'get_value',
argsJson: { key: 'hello' },
});
} catch (err) {
if (err instanceof RpcError) {
console.error(`RPC error ${err.code}: ${err.message}`);
} else if (err instanceof HTTPError) {
console.error(`HTTP ${err.status}: ${err.statusText}`);
} else if (err instanceof Error && err.name === 'AbortError') {
console.log('Request timed out or was cancelled');
}
}

See the error model for the full hierarchy, and the 401-handled-internally note.