brainzlab-js
v0.1.0
Published
BrainzLab browser SDK — front-end observability (reflex errors, recall logs, pulse RUM) for the BrainzLab fleet.
Maintainers
Readme
brainzlab-js
BrainzLab browser SDK — front-end observability for the BrainzLab fleet. The
JavaScript counterpart to the brainzlab Ruby gem:
| Module | Product | Captures |
|--------|---------|----------|
| reflex | reflex.brainzlab.ai | uncaught errors, promise rejections, React render errors, manual captureException |
| recall | recall.brainzlab.ai | logs (log()) + optional console.* capture |
| pulse | pulse.brainzlab.ai | Core Web Vitals (LCP/CLS/FID), navigation timing, fetch/XHR network timing |
| flux | flux.brainzlab.ai | custom events (trackEvent) + metrics (trackMetric) |
Zero runtime dependencies. ~5 KB gzipped core. SSR-safe (no-ops outside the browser).
Install
npm install brainzlab-jsQuick start
import * as BrainzLab from "brainzlab-js";
BrainzLab.init({
environment: "production",
release: import.meta.env.VITE_APP_VERSION,
appName: "roepa-admin",
// PUBLIC, write-only ingest keys — safe to ship in browser code.
// (sk_live_* secret keys are rejected by the browser endpoints.)
reflex: { ingestKey: "rfx_ingest_xxx" },
recall: { ingestKey: "rcl_ingest_xxx" },
pulse: { ingestKey: "pls_ingest_xxx" },
flux: { ingestKey: "flx_ingest_xxx" },
sampleRate: 1, // fraction of sessions for recall/pulse (errors + flux always sent)
captureConsole: true, // mirror console.* → recall
captureNetwork: true, // fetch/XHR timing → pulse
});Configure only the products you have keys for — each is optional.
API
BrainzLab.captureException(err, { feature: "checkout" }); // → reflex
BrainzLab.log("warn", "low stock", { sku }); // → recall
BrainzLab.trackEvent("offer.published", { offerId, plan }); // → flux event
BrainzLab.trackMetric("cart.value", 289000, { currency: "USD" }); // → flux metric
BrainzLab.setUser({ id: 42, email: "[email protected]" }); // attached to events
BrainzLab.flush(); // force-send buffered eventsReact
import { ErrorBoundary } from "brainzlab-js/react";
<ErrorBoundary fallback={(err) => <Crashed error={err} />}>
<App />
</ErrorBoundary>window.onerror doesn't catch React render errors — the ErrorBoundary does,
and forwards them to reflex with the component stack.
How it protects performance
- Async + batched. Events are buffered per product and flushed on a 5s timer,
when a batch fills, or with
fetch({ keepalive })/sendBeaconwhen the page is hidden — never on the critical path. - Preflight cached 24h. The cross-origin CORS preflight is cached, so steady state is a single background POST every few seconds.
- Sampling.
sampleRatethrottles recall/pulse volume; errors are always kept. - Safe by default. No-ops on SSR and on dev hosts (unless
enableInDevelopment).
Auth model
Browser code must never hold a secret key. Each product issues a public,
write-only *_ingest_* key (like a Sentry DSN); the endpoints validate the
origin and reject sk_live_*. Provision ingest keys per project in the product
console (or via the brainzlab gem provisioners).
Endpoint contract
OPTIONS {host}/api/v1/browser # CORS preflight
POST {host}/api/v1/browser # { events: [...], context: {...} }
Authorization: Bearer <*_ingest_* key>
X-BrainzLab-Session: <session id>