CrashSense
Error monitoring tells you WHAT crashed.
CrashSense tells you WHY โ and how to fix it.
Intelligent crash diagnosis for JavaScript, React & Vue โ root cause classification, not just stack traces.
The Problem
You see this in your error dashboard:
TypeError: Cannot read properties of undefined (reading 'map')
at UserList (UserList.tsx:42)
at renderWithHooks (react-dom.development.js:14985)
at mountIndeterminateComponent (react-dom.development.js:17811)
Cool. Now what? Is it a race condition? A failed API call? A memory leak? A hydration mismatch? You have no idea. Enjoy your next 3 hours of debugging.
The Solution
With CrashSense, the same crash gives you this:
{
category: "memory_issue",
subcategory: "memory_leak",
confidence: 0.87,
severity: "critical",
contributingFactors: [
{ factor: "high_memory_utilization", weight: 0.9, evidence: "Heap at 92% (487MB / 528MB)" },
{ factor: "memory_growing_trend", weight: 0.8, evidence: "Heap growing at 2.3MB/s over 60s" },
{ factor: "high_long_task_count", weight: 0.6, evidence: "4 long tasks in last 30s (avg 340ms)" },
],
system: {
memory: { trend: "growing", utilizationPercent: 92.2 },
cpu: { longTasksLast30s: 4, estimatedBlockingTime: 1360 },
network: { failedRequestsLast60s: 0, isOnline: true },
},
breadcrumbs: [
{ type: "navigation", message: "User navigated to /checkout" },
{ type: "click", message: "User clicked 'Add to Cart'" },
{ type: "network", message: "POST /api/cart โ 200 (142ms)" },
{ type: "console", message: "Warning: memory pressure elevated" },
],
aiAnalysis: {
rootCause: "Memory leak in useEffect โ event listener not cleaned up",
fix: { code: "return () => window.removeEventListener('resize', handler);" },
prevention: "Always return cleanup functions from useEffect with side effects",
}
}
Root cause identified. Fix suggested. Time saved: 3 hours.
Features
๐ 7 crash categories with confidence scoring โ memory_issue, event_loop_blocking, framework_react, framework_vue, network_induced, iframe_overload, runtime_error
๐ง AI-powered fix suggestions โ bring your own LLM (OpenAI, Anthropic, Google, or any compatible endpoint)
โก ~7KB gzipped core โ zero runtime dependencies in all browser packages
๐ก๏ธ Privacy-first โ emails, IPs, tokens, and credit card numbers auto-scrubbed at the SDK level
โ๏ธ React & Vue adapters โ hydration mismatch detection, infinite re-render tracking, reactivity loop detection
๐จ Pre-crash warnings โ 3-tier escalating alerts detect memory pressure before the tab dies
๐ Plugin system โ intercept, enrich, or drop crash events with custom plugins
๐ฆ TypeScript-first โ full type definitions, tree-shakeable ESM + CJS, SSR-safe
๐ Breadcrumb trail โ clicks, navigation, network requests, console output, state changes โ automatic
Install
npm install @crashsense/core
import { createCrashSense } from '@crashsense/core';
const cs = createCrashSense({
appId: 'my-app',
debug: true,
onCrash: (report) => {
console.log(report.event.category);
console.log(report.event.confidence);
console.log(report.event.contributingFactors);
},
});
That's it. CrashSense is now monitoring memory, event loop, network, and capturing every crash with full system state.
โ๏ธ React โ 3 lines to add crash diagnosis
npm install @crashsense/core @crashsense/react
import { CrashSenseProvider } from '@crashsense/react';
function App() {
return (
<CrashSenseProvider
config={{ appId: 'my-app', debug: true }}
onCrash={(report) => console.log('Crash:', report)}
>
<YourApp />
</CrashSenseProvider>
);
}
Automatically captures React-specific crashes: hydration mismatches, infinite re-render loops, hook ordering violations, and lifecycle errors.
Hooks
import { useCrashSense, useRenderTracker } from '@crashsense/react';
function Checkout() {
const { captureException, addBreadcrumb } = useCrashSense();
useRenderTracker('Checkout');
const handlePay = async () => {
addBreadcrumb({ type: 'click', message: 'User clicked pay' });
try {
await processPayment();
} catch (err) {
captureException(err, { action: 'payment' });
}
};
return <button onClick={handlePay}>Pay Now</button>;
}
๐ Vue โ plugin + composables
npm install @crashsense/core @crashsense/vue
import { createApp } from 'vue';
import { crashSensePlugin } from '@crashsense/vue';
const app = createApp(App);
app.use(crashSensePlugin, { appId: 'my-app', debug: true });
app.mount('#app');
Catches Vue-specific crashes: reactivity loops, lifecycle errors, component-level failures via app.config.errorHandler.
Composables
import { useCrashSense, useReactivityTracker } from '@crashsense/vue';
const { captureException, addBreadcrumb } = useCrashSense();
useReactivityTracker({
cartItems: () => store.state.cartItems,
userProfile: () => store.state.userProfile,
});
๐ง AI Integration โ bring your own LLM
npm install @crashsense/ai
import { createAIClient } from '@crashsense/ai';
const ai = createAIClient({
endpoint: 'https://api.openai.com/v1/chat/completions',
apiKey: process.env.OPENAI_API_KEY!,
model: 'gpt-4',
});
const analysis = await ai.analyze(report.event);
if (analysis) {
console.log('Root cause:', analysis.rootCause);
console.log('Explanation:', analysis.explanation);
console.log('Fix:', analysis.fix?.code);
console.log('Prevention:', analysis.prevention);
}
Supports OpenAI, Anthropic, Google, or any OpenAI-compatible endpoint. The AI client sends a structured, token-optimized crash payload and returns parsed, validated analysis.
CrashSense vs. The Rest
| Root cause classification | โ
7 categories + confidence | โ Stack trace only | โ | โ Basic grouping |
| Memory leak detection | โ
Trends + utilization | โ | โ | โ |
| Event loop blocking | โ
Long Task monitoring | โ | โ | โ |
| React crash detection | โ
Hydration, re-renders, hooks | โ ๏ธ ErrorBoundary only | โ ๏ธ Partial | โ ๏ธ Partial |
| Vue crash detection | โ
Reactivity loops, lifecycle | โ ๏ธ Partial | โ ๏ธ Partial | โ ๏ธ Partial |
| Pre-crash warnings | โ
3-tier escalation | โ | โ | โ |
| AI fix suggestions | โ
Bring your own LLM | โ | โ | โ |
| PII auto-scrubbing | โ
SDK-level | โ ๏ธ Server-side | โ | โ ๏ธ Limited |
| Bundle size (gzipped) | ~7KB | ~30KB | ~80KB | ~15KB |
| Runtime dependencies | 0 | Multiple | Multiple | Multiple |
| Open source | โ
MIT | โ
BSL | โ Proprietary | โ Proprietary |
| Pricing | Free | Free tier (5K events) | $99/mo | $59/mo |
Crash Categories
runtime_error | TypeError, ReferenceError, RangeError, etc. | Error type analysis |
memory_issue | Memory leaks, heap spikes, memory pressure | performance.memory + trend analysis |
event_loop_blocking | Infinite loops, long tasks, frozen UI | Long Task API + frame timing |
framework_react | Hydration mismatches, infinite re-renders, hook violations | React adapter instrumentation |
framework_vue | Reactivity loops, lifecycle errors, watcher cascades | Vue adapter instrumentation |
network_induced | Offline crashes, CORS blocks, timeouts, failed requests | Network monitoring + error analysis |
iframe_overload | Excessive iframes exhausting memory | MutationObserver + memory correlation |
Each crash report includes a confidence score (0.0โ1.0) and contributing factors with evidence strings, so you know exactly why the classifier made its decision.
Packages
Configuration
appId | string | required | Your application identifier |
environment | string | 'production' | Environment name |
release | string | '' | Release/version tag |
sampleRate | number | 1.0 | Event sampling rate (0โ1) |
maxEventsPerMinute | number | 30 | Rate limit for crash events |
enableMemoryMonitoring | boolean | true | Monitor memory usage and trends |
enableLongTaskMonitoring | boolean | true | Monitor event loop blocking |
enableNetworkMonitoring | boolean | true | Monitor network failures |
enableIframeTracking | boolean | false | Track iframe additions/removals |
enablePreCrashWarning | boolean | false | Enable 3-tier pre-crash warning system |
preCrashMemoryThreshold | number | 0.85 | Memory threshold for critical warnings |
piiScrubbing | boolean | true | Auto-scrub emails, IPs, tokens, card numbers |
debug | boolean | false | Log crash reports to console |
onCrash | (report) => void | โ | Callback when a crash is detected |
๐จ Pre-Crash Warning System
CrashSense detects dangerous system conditions before the browser tab crashes:
elevated | > 70% heap | > 5 iframes | System under pressure |
critical | > 85% heap | > 10 iframes | High risk โ take action |
imminent | > 95% heap | > 15 iframes | Crash likely seconds away |
const cs = createCrashSense({
appId: 'my-app',
enablePreCrashWarning: true,
enableIframeTracking: true,
enableMemoryMonitoring: true,
});
Warnings are automatically recorded as breadcrumbs. When a crash occurs, the trail shows the full escalation path.
๐ก Iframe Tracking
Uncontrolled iframe loading (ads, widgets, payment forms) can exhaust memory and crash the tab. CrashSense monitors iframe mutations in real-time:
const cs = createCrashSense({
appId: 'my-app',
enableIframeTracking: true,
});
const state = cs.getSystemState();
console.log('Total iframes:', state.iframe?.totalCount);
console.log('Cross-origin:', state.iframe?.crossOriginCount);
console.log('Origins:', state.iframe?.origins);
๐ Custom Plugins
Plugins intercept, enrich, or drop crash events before they reach your onCrash callback:
import type { CrashSensePlugin, CrashEvent, CrashSenseCore } from '@crashsense/core';
const backendReporter: CrashSensePlugin = {
name: 'backend-reporter',
setup(core: CrashSenseCore) {
console.log('Reporter initialized for', core.config.appId);
},
teardown() {},
onCrashEvent(event: CrashEvent) {
fetch('/api/crashes', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
category: event.category,
subcategory: event.subcategory,
severity: event.severity,
message: event.error.message,
fingerprint: event.fingerprint,
}),
}).catch(() => {});
return event;
},
};
const cs = createCrashSense({ appId: 'my-app' });
cs.use(backendReporter);
๐ค Sending Reports to Your Backend
const cs = createCrashSense({
appId: 'my-app',
onCrash: async (report) => {
await fetch('https://your-api.com/crashes', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(report),
});
},
});
Each report includes the full CrashEvent with system state, breadcrumbs, device info, contributing factors, and classification. PII is auto-scrubbed before it reaches your callback.
๐ Full Example โ React E-Commerce Checkout
import React, { useState, useEffect } from 'react';
import { CrashSenseProvider, useCrashSense, useRenderTracker } from '@crashsense/react';
import { createAIClient } from '@crashsense/ai';
const aiClient = createAIClient({
endpoint: 'https://api.openai.com/v1/chat/completions',
apiKey: process.env.REACT_APP_OPENAI_KEY!,
model: 'gpt-4',
});
export function App() {
return (
<CrashSenseProvider
config={{
appId: 'ecommerce-app',
environment: process.env.NODE_ENV,
release: '2.3.1',
enableIframeTracking: true,
enablePreCrashWarning: true,
onCrash: async (report) => {
await fetch('/api/crashes', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(report),
});
if (report.event.severity === 'critical') {
const analysis = await aiClient.analyze(report.event);
console.log('AI fix:', analysis?.fix?.code);
}
},
}}
>
<Checkout />
</CrashSenseProvider>
);
}
function Checkout() {
const { captureException, addBreadcrumb, core } = useCrashSense();
useRenderTracker('Checkout');
const [cart, setCart] = useState([]);
useEffect(() => {
const user = JSON.parse(localStorage.getItem('user') || '{}');
if (user.id) core?.setUser({ id: user.id, plan: user.plan });
}, [core]);
async function handleCheckout() {
addBreadcrumb({ type: 'click', message: 'User clicked checkout' });
try {
const res = await fetch('/api/checkout', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ items: cart }),
});
if (!res.ok) throw new Error(`Checkout failed: ${res.status}`);
} catch (error) {
captureException(error, { action: 'checkout', cartSize: String(cart.length) });
}
}
return <button onClick={handleCheckout}>Complete Purchase</button>;
}
See full source: examples/react-ecommerce/
Performance Budget
| CPU overhead | < 2% |
| Memory footprint | < 5MB |
| Core bundle (gzipped) | < 15KB |
| SDK errors | NEVER crash the host app |
All monitoring uses passive browser APIs (PerformanceObserver, MutationObserver). Zero monkey-patching by default.
Browser Support
| Chrome | 80+ |
| Firefox | 80+ |
| Safari | 14+ |
| Edge | 80+ |
| Node.js | 18+ |
performance.memory is Chrome-only. Memory monitoring gracefully degrades in other browsers. All other features work cross-browser.
Development
git clone https://github.com/hoainho/crashsense.git
cd crashsense
npm install
npm run build
npm test
Monorepo with npm workspaces. Each package builds with tsup (ESM + CJS + DTS).
crashsense/
packages/
types/ # Shared TypeScript types
utils/ # Ring buffer, event bus, fingerprint, PII scrubber
core/ # Crash detection engine, classifiers, monitors
react/ # ErrorBoundary, hooks, hydration detector
vue/ # Plugin, composables, reactivity tracker
ai/ # LLM client, payload builder, response parser
examples/
react-ecommerce/
Contributing
Contributions are welcome. Whether it's a bug report, feature request, or pull request โ all help is appreciated.
- Fork the repo
- Create your branch (
git checkout -b feat/amazing-feature)
- Commit your changes (
git commit -m 'Add amazing feature')
- Push to the branch (
git push origin feat/amazing-feature)
- Open a Pull Request
See open issues for ideas.
Changelog
v1.0.0 (2026)
- Initial public release
- 7 crash categories with confidence scoring and contributing factors
- React and Vue framework adapters
- AI-powered root cause analysis (OpenAI, Anthropic, Google, custom endpoints)
- Iframe tracking via MutationObserver
- Pre-crash warning system with 3-tier escalation
- Plugin system for extensibility
- PII scrubbing (emails, IPs, tokens, credit cards)
- Zero runtime dependencies in all browser packages
License
MIT โ Copyright (c) 2026 hoainho
Author
Hoai Nho โ GitHub ยท npm ยท hoainho.work@gmail.com
If CrashSense saves you debugging time, โญ star the repo โ it helps others find it.