Features · Install · Usage · Architecture · Platform
The error-tracking platform we wished was already in our stack. You ship a deploy; somewhere out there a webpack chunk is 404'ing for one user and your sign-in page is silently broken. Your error boundary
console.errors into the void, and your only signal is the support ticket that arrives forty minutes later.@smooai/observabilityfills that gap: automatic capture and grouping across every runtime, your events going to your Smoo backend only.
Browser
- 🛑 Uncaught exceptions —
window.onerror,unhandledrejection,console.errortaps - 🍞 Breadcrumbs —
fetch/XHRcalls, click events, navigation events, custom traces - 🧭 Release tagging — every event ships with the git sha so symbolication is one click away
- 🗺️ Source maps — uploaded to S3 at build time, applied lazily on view
- 🚪 Beacon flush — events queued at
pagehideship vianavigator.sendBeacon - 💾 Offline queue — events captured while offline persist in
IndexedDBand retry on focus - 🔐 PII scrub —
password,token,Bearer ..., and friends are redacted before transport
Node
- 🛑
uncaughtException+unhandledRejectionwith full stack - 🪢 Hono middleware — captures errors propagating to the global
onErrorhandler - 🧠 AsyncLocalStorage scope — per-request user, tags, breadcrumbs without leaking across requests
- 📦 Batched transport —
undiciwith retry / backoff - 🔐 Same PII scrub policy as the browser
React / Next.js
- 🧱
<ErrorBoundary>— drop-in component, captures and renders your fallback - ⚓
useErrorHandler()— for async event-handler errors React boundaries can't see - 🏗️
withSmooObservability(nextConfig)— enables production browser source maps and uploads them in CI - 🛡️
<RootErrorBoundary>— drop intoapp/global-error.tsx/app/error.tsx
console.log/console.info/console.warn— onlyconsole.erroris tapped, and that's opt-out- HTTP request bodies — only method, path, status, and duration appear in breadcrumbs
- Anything matching the PII scrub regex unless you explicitly allowlist it
pnpm add @smooai/observability # core (browser + Node)
pnpm add @smooai/observability-react # React bindings
pnpm add @smooai/observability-next # Next.js wrapperor with npm / yarn / bun — same names.
| Package | npm | Purpose |
|---|---|---|
@smooai/observability |
Core client — browser + Node universal | |
@smooai/observability-react |
React <ErrorBoundary> + useErrorHandler |
|
@smooai/observability-next |
Next.js wrapper + sourcemap upload |
// next.config.ts
import { withSmooObservability } from '@smooai/observability-next/build';
export default withSmooObservability(
{
/* your config */
},
{
org: 'your-org',
release: process.env.GITHUB_SHA ?? 'dev',
uploadSourcemaps: process.env.CI === 'true',
},
);// instrumentation.ts
export async function register() {
const { Client } = await import('@smooai/observability');
Client.init({
dsn: process.env.OBSERVABILITY_INGEST_URL!,
environment: process.env.STAGE,
release: process.env.GITHUB_SHA ?? 'dev',
});
}// app/global-error.tsx
'use client';
import { RootErrorBoundary } from '@smooai/observability-next';
export default function GlobalError({ error, reset }: { error: Error & { digest?: string }; reset: () => void }) {
return (
<html>
<body>
<RootErrorBoundary error={error} resetError={reset} fallback={<YourBrandedError onRetry={reset} />} />
</body>
</html>
);
}import { Client } from '@smooai/observability';
Client.init({
dsn: process.env.SMOO_OBSERVABILITY_DSN!,
environment: 'production',
release: import.meta.env.VITE_GIT_SHA,
});
Client.setUser({ id: 'user_abc', orgId: 'org_xyz' });import { Client, observabilityMiddleware } from '@smooai/observability/node';
Client.init({
dsn: process.env.OBSERVABILITY_INGEST_URL!,
environment: process.env.STAGE!,
release: process.env.LAMBDA_FUNCTION_VERSION ?? 'dev',
});
app.use('*', observabilityMiddleware());The same ingest contract (POST /webhooks/observability/{org_id}/{token} with type: 'error') accepts events from any language. Follow-up SDKs:
- 🐍 Python —
smooai-observabilityon PyPI (tracked in SMOODEV-1067 follow-ups) - 🦀 Rust —
smooai-observabilitycrate (tracked in SMOODEV-1067 follow-ups) - 🐹 Go —
github.com/smooai/observability-go(tracked in SMOODEV-1067 follow-ups) - 💠 .NET —
SmooAI.Observabilityon NuGet (tracked in SMOODEV-1067 follow-ups)
The SDK is intentionally thin. It captures, batches, redacts PII, and POSTs to a Smoo ingest endpoint. All of the heavy lifting — fingerprint grouping, source-map symbolication, dashboards, alerts, retention — lives in the Smoo platform.
%%{init: {'theme':'base','themeVariables':{
'background':'#020618','primaryColor':'#0b1426','primaryTextColor':'#e6edf6','primaryBorderColor':'#2b3a52',
'lineColor':'#7c8aa0','secondaryColor':'#0b1426','tertiaryColor':'#0b1426','fontFamily':'ui-sans-serif, system-ui, sans-serif',
'clusterBkg':'#0b1426','clusterBorder':'#22304a'}}}%%
flowchart LR
REACT["observability-react<br/>ErrorBoundary · useErrorHandler"] -->|wraps| CORE
NEXT["observability-next<br/>withSmooObservability · sourcemaps"] -->|wraps| CORE
CORE["@smooai/observability<br/>capture · scope · scrub · batch"]
CORE -->|"POST /webhooks/observability/{org}/{token}<br/>Bearer B2M JWT · gzipped JSON"| INGEST[("Smoo platform<br/>group · symbolicate · alert")]
classDef warm fill:#f49f0a,stroke:#ff6b6c,color:#1a0f00;
classDef teal fill:#00a6a6,stroke:#00c2c2,color:#011;
class CORE warm
class INGEST teal
Full backend architecture: SmooAI/smooai → docs/Architecture/Observability-Architecture.md.
- TypeScript — strict mode, ESM-only, dual browser/Node entries via package
exportsmap - tsup — bundling, dual ESM/types output, sourcemaps
- turborepo — fast pipeline across the three packages
- vitest — unit tests
- changesets — versioning + npm publish via GitHub Actions
This SDK is opinionated about privacy:
- We never capture form bodies, request bodies, or response bodies by default
- We never capture cookies
- We never send anything to a third-party service — your events go to your Smoo backend only
- PII scrubbing is enabled by default and can be tuned per-tenant
0.1.0 — types and client skeleton are stable. The capture handlers, stack parsers, transport, and source-map upload land incrementally in upcoming 0.x releases. The backend ingest, fingerprint grouping, dashboard, and customer-org rollout live in the SmooAI/smooai monorepo and are tracked under SMOODEV-1067.
@smooai/observability is built and open-sourced by Smoo AI — the AI-powered business platform with AI built into every product: CRM, customer support, campaigns, field service, observability, and developer tools.
- 🚀 Observability on the platform — smoo.ai/platform/observability
- 🧰 More open source from Smoo AI — smoo.ai/open-source
- 🧩 Sibling packages — @smooai/logger, @smooai/config, @smooai/fetch, smooth (the
thCLI)
Issues and PRs welcome. Maintained by Brent Rager — email · LinkedIn · BlueSky · TikTok · Instagram.
MIT © Smoo AI, Inc. See LICENSE.
Built by Smoo AI — AI built into every product.
