Lightweight JavaScript and React error tracking client for Errflow - a self-hosted error monitoring backend.
Errflow is a self-hosted error tracking system consisting of:
- Errflow Backend - A FastAPI server that ingests, stores, and manages error events
- errflow-js (this package) - A lightweight client library for capturing JavaScript and React errors
This client captures errors from your web application and sends them to your local Errflow backend over HTTP.
- Automatic capture of uncaught errors and unhandled promise rejections
- Manual error and message capture
- Breadcrumb trail for debugging context
- Rate limiting to prevent event floods
- Zero external dependencies
- Works with vanilla JavaScript and React
npm install errflow-jsOr link locally for development:
cd errflow-js
npm install
npm run buildimport { createErrflowClient } from 'errflow-js';
// Create the client - this also attaches global error handlers
const errflow = createErrflowClient({
endpoint: 'http://localhost:8000/api/v1/events',
projectKey: 'demo-web',
projectSecret: 'demo-secret',
environment: 'dev',
release: 'my-app@1.0.0'
});
// Add breadcrumbs for context
errflow.addBreadcrumb('navigation', 'User visited /dashboard');
// Manually capture errors
try {
dangerousOperation();
} catch (error) {
errflow.captureException(error, {
tags: { component: 'Dashboard' }
});
}
// Capture messages
errflow.captureMessage('User completed onboarding', { level: 'warn' });
// Set user context
errflow.setUser({ id: 'user-123', email: 'user@example.com' });
// Clean up when done
errflow.shutdown();Creates a new Errflow client instance.
| Option | Type | Default | Description |
|---|---|---|---|
endpoint |
string | 'http://localhost:8000/api/v1/events' |
Backend endpoint URL |
projectKey |
string | 'demo-web' |
Project identifier sent in X-Project-Key header |
projectSecret |
string | 'demo-secret' |
Secret sent in Authorization header |
platform |
string | 'react' |
Platform identifier ('react' or 'js') |
environment |
string | 'dev' |
Environment ('dev', 'staging', 'prod') |
release |
string | 'demo-web@0.1.0' |
Release version |
user |
object | { id: 'demo-user', email: null } |
Default user context |
tags |
object | {} |
Default tags |
enabled |
boolean | true |
Enable or disable the client |
maxBreadcrumbs |
number | 20 |
Maximum breadcrumbs to keep |
rateLimit |
object | { maxEvents: 5, perSeconds: 10 } |
Rate limiting configuration |
autoBreadcrumbs |
boolean | true |
Enable automatic breadcrumb capture |
Capture an error and send it to the backend.
try {
throw new Error('Something went wrong');
} catch (error) {
await errflow.captureException(error, {
level: 'error',
tags: { module: 'auth' },
user: { id: 'user-456' }
});
}Capture a message and send it to the backend.
await errflow.captureMessage('Payment processed', {
level: 'warn',
tags: { amount: '99.99' }
});Add a breadcrumb for debugging context. Note: With autoBreadcrumbs: true (default), most breadcrumbs are captured automatically.
// Manual breadcrumbs (optional when autoBreadcrumbs is enabled)
errflow.addBreadcrumb('custom', 'User completed checkout flow');When autoBreadcrumbs: true (default), the library automatically captures:
| Type | What is captured |
|---|---|
ui.click |
Clicks on buttons, links, inputs, and interactive elements |
navigation |
Page loads, History API (pushState, replaceState, popstate) |
http |
fetch() and XMLHttpRequest calls with status codes |
console.log/warn/error/info |
Console output (truncated to 100 chars) |
Example auto-captured breadcrumbs:
[navigation] page load: /dashboard
[ui.click] button "Add to Cart"
[http] POST /api/cart [200]
[console.log] User added item 123
[navigation] pushState: /checkout
[ui.click] button "Submit Order"
[http] POST /api/orders [500]
[console.error] Order failed: server error
To disable auto-breadcrumbs:
const errflow = createErrflowClient({
autoBreadcrumbs: false
});
// Now you must add breadcrumbs manually
errflow.addBreadcrumb('ui', 'Button clicked');Set the current user context.
errflow.setUser({
id: 'user-123',
email: 'user@example.com'
});Add or update tags.
errflow.setTags({
version: '2.0.0',
feature_flag: 'new_checkout'
});Flush any pending events (currently a no-op as events are sent immediately).
Shutdown the client and remove all global error handlers.
errflow.shutdown();The example app demonstrates all features of errflow-js with a visual interface.
- Start the Errflow backend on
http://localhost:8000
# In the errflow backend repository
cd errflow-backend
uvicorn app.main:app --reload- Build the library (optional - example uses local source)
# In this repository
npm install
npm run build- Start the example app
cd example
npm install
npm run dev- Open http://localhost:5173 in your browser
- Configuration panel to adjust endpoint, credentials, and settings
- Buttons to trigger various error scenarios
- Live display of captured errors and server responses
- Breadcrumb trail visualization
The client sends POST requests to:
POST http://localhost:8000/api/v1/events
Content-Type: application/json
X-Project-Key: <projectKey>
Authorization: Bearer <projectSecret>
{
"platform": "react",
"environment": "dev",
"release": "demo-web@0.1.0",
"level": "error",
"timestamp": "2024-01-15T10:30:00.000Z",
"exception": {
"name": "TypeError",
"message": "Cannot read property 'foo' of undefined",
"stack": "TypeError: Cannot read property..."
},
"request": {
"url": "http://localhost:5173/",
"user_agent": "Mozilla/5.0..."
},
"tags": {},
"user": {
"id": "demo-user",
"email": null
},
"breadcrumbs": [
{
"type": "ui",
"message": "clicked button",
"timestamp": "2024-01-15T10:29:55.000Z"
}
]
}The backend should return:
{
"issue_id": "uuid",
"event_id": "uuid",
"fingerprint": "hash"
}The Errflow backend must allow CORS requests from your frontend origin. Ensure the backend is configured with:
# In FastAPI backend
from fastapi.middleware.cors import CORSMiddleware
app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:5173"], # Your frontend URL
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)Symptom: Server response shows network error or timeout.
Solution: Ensure the Errflow backend is running:
curl http://localhost:8000/healthSymptom: Browser console shows CORS policy errors.
Solution: Configure CORS on the backend to allow your frontend origin. Check that http://localhost:5173 (or your actual origin) is in the allowed origins list.
Symptom: Events fail to send with network errors.
Solution:
- Check that the endpoint URL is correct
- Verify the backend is accessible from your browser
- Check for firewall or proxy issues
Symptom: Events are dropped silently.
Solution: The default rate limit is 5 events per 10 seconds. Adjust the rateLimit option if needed:
const errflow = createErrflowClient({
rateLimit: { maxEvents: 10, perSeconds: 10 }
});Symptom: No errors in console but events do not appear in backend.
Solution:
- Check the
enabledoption istrue - Verify credentials match backend configuration
- Check backend logs for authentication errors
npm install
npm run buildnpm run devcd example
npm install
npm run devMIT
Note: This is a lightweight alternative to heavy error tracking SDKs. It focuses on simplicity and zero external dependencies while providing essential error tracking capabilities.