@ihyeon/browser-error-log
v0.1.10
Published
A small, framework-independent browser error SDK for a collector you control.
Maintainers
Readme
@ihyeon/browser-error-log
English | 한국어
A small browser error SDK for a collector you control. Use your own backend or the repository's self-hosted Node.js collector, which stores events in SQLite or rotating JSONL files.
Why use it?
- Choose where events go. There is no built-in hosted endpoint or separate analytics destination. Configure
endpointor supply your owntransport. - Keep the browser dependency small. No runtime framework dependency; ESM, CommonJS, and TypeScript declarations are provided. The repository enforces a 20 KiB gzip budget for the browser SDK, excluding the viewer and optional React adapter.
- Control events before delivery. Filter or edit them with
beforeSend, remove path identifiers withsanitizeUrl, and choose which HTTP responses matter withshouldCaptureHttp. - Start with useful error context. Collect JavaScript exceptions, unhandled promises, fetch/XHR failures, and manually reported errors, with project, release, page, and occurrence time. Console capture is opt-in.
- Keep storage portable. The companion collector offers SQLite with a live viewer, or JSONL logs that can be exported and inspected locally. You can implement the same versioned contract in your own backend.
Install
npm install @ihyeon/browser-error-logThe @ihyeon/browser-error-log-protocol dependency resolves from npm. For local source-checkout development, use Node.js 24, npm ci, and npm run check:package, then install the protocol and browser tarballs together as shown in the SDK guide.
Connect in three steps
In the source checkout, start your collector. Set the exact origin of the app that will send events:
MICRO_PROJECTS=my-web MICRO_ALLOWED_ORIGINS=http://localhost:5173 npm run microIn your app's browser entry point, initialize once:
import { init } from '@ihyeon/browser-error-log'; export const errorLog = init({ project: 'my-web', endpoint: 'http://127.0.0.1:4319/api/events', environment: 'development', release: 'my-release', });Send a diagnostic error, then open
http://127.0.0.1:4319/:errorLog.captureException(new Error('Connection check')); await errorLog.flush(); console.log(errorLog.getStats()); // sent: 1 when delivery succeeds
Keep the client alive for the app's lifetime. Use destroy() for test cleanup or when disposing the app; it removes instrumentation and discards pending events. flush() completes the SDK's delivery attempts, not a guarantee of storage: check getStats() and the collector. sent also counts events accepted by the browser's sendBeacon queue when the tab is hidden; this does not confirm collector storage. Capturing starts only after initialization.
Use the self-hosting guide for external hosting. Production apps need their own HTTPS collector, exact allowed origins, persistent storage, and viewer authentication. localhost and 127.0.0.1 are different origins. The viewer password belongs only on the server; do not put it in SDK configuration.
Capture handled errors
try {
await loadDashboard();
} catch (error) {
errorLog.captureException(error, { context: { action: 'load-dashboard' } });
}The optional @ihyeon/browser-error-log-react package provides an Error Boundary. The base SDK does not require React. Imports and initialization are safe during SSR but do not collect server-side errors; initialize in your framework's browser/client entry point.
Collection controls
const errorLog = init({
project: 'my-web',
endpoint: '/api/events', // your collector or a same-origin proxy
captureConsole: false,
beforeSend(event) {
if (event.message.includes('Expected diagnostic')) return null;
return event;
},
sanitizeUrl(url) {
return url.replace(/\/users\/[^/?#]+/g, '/users/:id');
},
shouldCaptureHttp(status) {
return status >= 500;
},
});By default, HTTP capture records 5xx responses and network failures, excludes intentional aborts, and excludes the collector endpoint. The SDK strips URL queries, fragments, and credentials and masks common email/token patterns. It does not collect request/response bodies, cookies, DOM, form inputs, or session recordings. Error text, URL paths, stacks, and custom context may still contain sensitive data; set application-specific filters. A failing beforeSend or sanitizeUrl drops the event.
For a custom transport(batch, { signal }), pass signal to your request and reject on delivery failure. Include endpoint for collector exclusion if you want automatic network capture; otherwise network capture is disabled for a custom transport. The default transport omits credentials.
Delivery limits
The default queue holds 50 events and flushes every 10 seconds. Batches contain up to 20 events or 48,000 bytes. Each attempt has a 5-second deadline; retryable failures get up to two retries. maxQueueSize, flushIntervalMs, and transportTimeoutMs are configurable within bounded ranges. These are best-effort limits: offline operation, tab closure, buffer overflow, or exhausted retries can lose events. There is no persistent offline queue or exactly-once guarantee.
Hosting and costs
This project distributes software, not a managed monitoring service. Infrastructure is not included. Hosting, servers, databases, storage, bandwidth, domains, backups, and third-party services are selected and paid for by each operator. Any charges are billed independently by their providers, not by this project or its maintainers. Self-hosting does not mean that your infrastructure is free.
