Bundling & runtimes
Mero.js is a zero-dependency package built on Web Platform APIs. This guide covers how it’s packaged, which runtimes support which features, and the browser-specific concerns (CORS, SSR).
Module formats
Section titled “Module formats”The package is "type": "module" and ships three builds, selected automatically
through its exports map:
| Condition | File | Format |
|---|---|---|
import (bundlers, Node ESM) |
dist/index.mjs |
ESM |
require (Node CommonJS) |
dist/index.cjs |
CommonJS |
browser (bundler browser target) |
dist/index.browser.mjs |
ESM, minified |
types |
dist/index.d.ts |
TypeScript declarations |
// ESM / TypeScriptimport { createMeroJs } from '@calimero-network/mero-js';// CommonJSconst { createMeroJs } = require('@calimero-network/mero-js');The package sets "sideEffects": false, so a modern bundler (esbuild, Rollup,
Vite, webpack) tree-shakes away everything you don’t import — pull in just
createMeroJs, or only a helper like withRetry, and the rest is dropped.
Runtime support
Section titled “Runtime support”The HTTP and SSE surfaces run on every modern runtime. The WebSocket client and the browser-only helpers have narrower support:
| Feature | Browser | Node 18–21 | Node 22+ | Deno / Bun | Edge workers |
|---|---|---|---|---|---|
sdk.admin / sdk.auth / sdk.rpc (fetch) |
✅ | ✅ | ✅ | ✅ | ✅ |
sdk.events (SSE, fetch streaming) |
✅ | ✅ | ✅ | ✅ | ⚠️¹ |
sdk.ws (needs global WebSocket) |
✅ | ❌² | ✅ | ✅ | ⚠️¹ |
LocalStorageTokenStore |
✅ | ❌³ | ❌³ | ❌³ | ❌³ |
CloudClient (window.open) |
✅ | ❌ | ❌ | ❌ | ❌ |
- Edge runtimes restrict long-lived
fetchstreams and outboundWebSocket; check your platform’s limits before relying on live event streams there. - Node gained a global
WebSocketin v22. On 18–21,sdk.wsthrows unless you install aWebSocketpolyfill ontoglobalThis. Prefersdk.events(SSE) server-side. - Falls back to a no-op /
nulloff the browser (it guardstypeof localStorage). UseMemoryTokenStore, or a customTokenStore, on the server.
CORS (browser → node)
Section titled “CORS (browser → node)”A browser app calling a merod node on a different origin is a cross-origin
request, so the node must return the appropriate CORS headers
(Access-Control-Allow-Origin, and for preflight Access-Control-Allow-Methods
/ -Headers). Because the SDK authenticates with an Authorization: Bearer
header, requests are non-simple and the browser sends a preflight OPTIONS the
node must answer. A CORS rejection surfaces as an
HTTPError with status: 0 (the browser
hides the details from JavaScript). Only set requestCredentials: 'include' if
the node authenticates with cookies — with bearer tokens you don’t need it.
SSR / server rendering
Section titled “SSR / server rendering”A few APIs touch browser globals and must be guarded (or only called client-side) in Next.js / Remix / SvelteKit:
LocalStorageTokenStore— safe to construct anywhere (returnsnullon the server), but it only persists in the browser.MeroJs.parseAuthCallback()/parseAuthCallback()— readwindow.locationand callhistory.replaceState; browser-only.CloudClient.enableHA/disableHA— callwindow.open; browser-only.
Everything else (sdk.admin, sdk.auth, sdk.rpc, sdk.events) works on the
server. For a server-only MeroJs, pass a MemoryTokenStore (or your own store)
and drive baseUrl/credentials from environment variables.