@faultscope/node

Universal FaultScope SDK for Node.js, Express, Fastify, Koa, NestJS, Next.js, Nuxt, React, Vue and more.
Install
npm install @faultscope/node
Latest Version:1.1.0
License:MIT
Last Updated:Sep 25, 2026
Links: GitHub  ·  npm
Maintainer: jaykaneriya

@faultscope/node

Universal FaultScope SDK — zero runtime dependencies.
Works with Node.js, Express, Fastify, Koa, NestJS, Next.js, Nuxt, React, Vue and any Node.js framework.

npm version license


Table of Contents


Install

# From npm (after publishing)
npm install @faultscope/node

# From local monorepo (during development)
npm install ./platform/sdk/node

# Or link globally for testing
cd platform/sdk/node && npm link
cd your-project && npm link @faultscope/node

Environment Variables

Set these in your .env / .env.local file:

# Server-side (Node, Express, Fastify, Koa, NestJS, Next.js server)
FAULTSCOPE_DSN=https://your-hub.example.com/api/ingest/batch
FAULTSCOPE_KEY=your-api-key

# Client-side (React, Vue, Nuxt client, Next.js error.tsx)
# Vite / Next.js: prefix with NEXT_PUBLIC_ or VITE_
NEXT_PUBLIC_FAULTSCOPE_DSN=https://your-hub.example.com/api/ingest/batch
NEXT_PUBLIC_FAULTSCOPE_KEY=your-api-key

VITE_FAULTSCOPE_DSN=https://your-hub.example.com/api/ingest/batch
VITE_FAULTSCOPE_KEY=your-api-key

Sub-packages

Import path Framework Runtime
@faultscope/node Vanilla Node.js Server
@faultscope/node/express Express.js Server
@faultscope/node/fastify Fastify Server
@faultscope/node/koa Koa.js Server
@faultscope/node/nestjs NestJS Server
@faultscope/node/nextjs Next.js Server + Client
@faultscope/node/react React Browser
@faultscope/node/vue Vue 3 Browser
@faultscope/node/nuxt Nuxt 3 Server + Browser
@faultscope/node/browser Any browser app Browser

Node.js (Vanilla / HTTP)

Works with any Node.js application. Auto-hooks uncaughtException, unhandledRejection, SIGTERM, and SIGINT.

import FaultScope from '@faultscope/node';
// or: const { FaultScope } = require('@faultscope/node');

FaultScope.init({
  dsn: process.env.FAULTSCOPE_DSN!,
  apiKey: process.env.FAULTSCOPE_KEY!,
  environment: process.env.NODE_ENV,   // optional
  release: process.env.APP_VERSION,    // optional
  debug: false,                         // optional: log to console
});

// Manual capture
try {
  await riskyOperation();
} catch (err) {
  FaultScope.captureException(err, { context: 'background-job' });
}

// Flush all buffered events (e.g. before process exit)
FaultScope.flush();

Express

import express from 'express';
import { init, requestMiddleware, errorHandler, asyncHandler } from '@faultscope/node/express';

init({
  dsn: process.env.FAULTSCOPE_DSN!,
  apiKey: process.env.FAULTSCOPE_KEY!,
});

const app = express();

// Optional: enriches request context & flushes on response finish
app.use(requestMiddleware());

// Your routes
app.get('/users', asyncHandler(async (req, res) => {
  const users = await db.getUsers();
  res.json(users);
}));

// FaultScope error handler — MUST be last middleware
app.use(errorHandler());
// or with options:
app.use(errorHandler({ includeBody: true, tags: { service: 'api' } }));

app.listen(3000);

Fastify

import Fastify from 'fastify';
import { init, faultScopePlugin, asyncHandler } from '@faultscope/node/fastify';

init({
  dsn: process.env.FAULTSCOPE_DSN!,
  apiKey: process.env.FAULTSCOPE_KEY!,
});

const app = Fastify();

await app.register(faultScopePlugin, {
  includeBody: false,  // optional
  includeQuery: true,  // optional (default: true)
  tags: { service: 'api' },  // optional
});

app.get('/users', asyncHandler(async (req, reply) => {
  return db.getUsers();
}));

await app.listen({ port: 3000 });

Koa

import Koa from 'koa';
import Router from '@koa/router';
import { init, errorMiddleware } from '@faultscope/node/koa';

init({
  dsn: process.env.FAULTSCOPE_DSN!,
  apiKey: process.env.FAULTSCOPE_KEY!,
});

const app = new Koa();
const router = new Router();

// MUST be first — wraps all downstream middleware
app.use(errorMiddleware({ includeBody: false }));

router.get('/users', async (ctx) => {
  ctx.body = await db.getUsers();
});

app.use(router.routes());
app.listen(3000);

NestJS

1. Initialize in main.ts

// main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { Catch, Injectable, ArgumentsHost } from '@nestjs/common';
import { init, FaultScopeFilter } from '@faultscope/node/nestjs';

// Extend and decorate the filter in YOUR code
@Catch()
export class AppExceptionFilter extends FaultScopeFilter {}

async function bootstrap() {
  init({
    dsn: process.env.FAULTSCOPE_DSN!,
    apiKey: process.env.FAULTSCOPE_KEY!,
  });

  const app = await NestFactory.create(AppModule);
  app.useGlobalFilters(new AppExceptionFilter());
  await app.listen(3000);
}
bootstrap();

2. Optional Interceptor with rxjs (NestJS ships with rxjs)

// app.interceptor.ts
import { Injectable, ExecutionContext, CallHandler } from '@nestjs/common';
import { tap } from 'rxjs/operators';
import { FaultScopeInterceptor, captureException } from '@faultscope/node/nestjs';

@Injectable()
export class AppInterceptor extends FaultScopeInterceptor {
  intercept(context: ExecutionContext, next: CallHandler) {
    return next.handle().pipe(
      tap({ error: (err) => captureException(err, { framework: 'nestjs' }) })
    );
  }
}

// main.ts
app.useGlobalInterceptors(new AppInterceptor());

3. Manual capture in services

import { captureException } from '@faultscope/node/nestjs';

@Injectable()
export class UsersService {
  async getUsers() {
    try {
      return await this.db.find();
    } catch (err) {
      captureException(err, { service: 'UsersService' });
      throw err;
    }
  }
}

Next.js

Step 1 — instrumentation.ts (root of project)

// instrumentation.ts
export { register } from '@faultscope/node/nextjs';

For Next.js < 14.1, enable the hook in next.config.js:

experimental: { instrumentationHook: true }

Step 2 — App Router API routes

// app/api/example/route.ts
import { withFaultScope } from '@faultscope/node/nextjs';

export const GET = withFaultScope(async (req) => {
  return Response.json({ status: 'ok' });
});

Step 3 — App Router error.tsx

// app/error.tsx
'use client';
import { useEffect } from 'react';
import { reportBoundaryError } from '@faultscope/node/nextjs';

export default function ErrorBoundary({ error }: { error: Error }) {
  useEffect(() => {
    reportBoundaryError(error, {
      dsn: process.env.NEXT_PUBLIC_FAULTSCOPE_DSN!,
      apiKey: process.env.NEXT_PUBLIC_FAULTSCOPE_KEY!,
    });
  }, [error]);
  return <h2>Something went wrong!</h2>;
}

Step 4 — Pages Router (optional)

// pages/api/users.ts
import { withFaultScopeApi } from '@faultscope/node/nextjs';

export default withFaultScopeApi(async (req, res) => {
  res.json(await db.getUsers());
});
// pages/dashboard.tsx
import { withFaultScopeSSR } from '@faultscope/node/nextjs';

export const getServerSideProps = withFaultScopeSSR(async (ctx) => {
  return { props: { data: await fetchData() } };
});

React

Vite / CRA — main.tsx

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { initBrowser } from '@faultscope/node/react';

initBrowser({
  dsn: import.meta.env.VITE_FAULTSCOPE_DSN,
  apiKey: import.meta.env.VITE_FAULTSCOPE_KEY,
  environment: import.meta.env.MODE,
});

ReactDOM.createRoot(document.getElementById('root')!).render(<App />);

Error boundary (functional)

// components/ErrorBoundary.tsx
'use client'; // if Next.js App Router
import { useEffect } from 'react';
import { useReportError } from '@faultscope/node/react';

export default function ErrorBoundary({ error }: { error: Error }) {
  useReportError(error);  // captures to FaultScope
  return <div>Something went wrong.</div>;
}

Error boundary (class component)

import { Component } from 'react';
import { reportClassBoundaryError } from '@faultscope/node/react';

class ErrorBoundary extends Component {
  componentDidCatch(error: Error, info: React.ErrorInfo) {
    reportClassBoundaryError(error, { component_stack: info.componentStack });
  }
  render() {
    return this.props.children;
  }
}

Async event handler wrapper

import { captureAsync } from '@faultscope/node/react';

<button onClick={captureAsync(async () => {
  await submitForm();
})}>Submit</button>

Vue 3

Vite — main.ts

import { createApp } from 'vue';
import App from './App.vue';
import { createFaultScopePlugin } from '@faultscope/node/vue';

const app = createApp(App);

app.use(createFaultScopePlugin({
  dsn: import.meta.env.VITE_FAULTSCOPE_DSN,
  apiKey: import.meta.env.VITE_FAULTSCOPE_KEY,
  environment: import.meta.env.MODE,
  captureWarnings: import.meta.env.DEV, // optional: capture Vue warnings in dev
}));

app.mount('#app');

In components / composables

// composables/useApi.ts
import { useFaultScope } from '@faultscope/node/vue';

export function useApi() {
  const { captureException } = useFaultScope();

  async function fetchData() {
    try {
      return await api.getData();
    } catch (err) {
      captureException(err, { composable: 'useApi' });
      throw err;
    }
  }

  return { fetchData };
}

Nuxt 3

Server plugin — plugins/faultscope.server.ts

import { createServerPlugin } from '@faultscope/node/nuxt';

export default createServerPlugin({
  dsn: process.env.FAULTSCOPE_DSN!,
  apiKey: process.env.FAULTSCOPE_KEY!,
  environment: process.env.NODE_ENV,
});

Client plugin — plugins/faultscope.client.ts

import { createClientPlugin } from '@faultscope/node/nuxt';

export default createClientPlugin({
  dsn: import.meta.env.VITE_FAULTSCOPE_DSN,
  apiKey: import.meta.env.VITE_FAULTSCOPE_KEY,
});

Composable in pages / components

<script setup>
import { useFaultScope } from '@faultscope/node/nuxt';

const { captureException, captureMessage, setUser } = useFaultScope();

async function saveData() {
  try {
    await $fetch('/api/save', { method: 'POST', body: form.value });
  } catch (err) {
    captureException(err, { page: 'profile' });
  }
}
</script>

Browser (Universal Client-side)

Use this for any non-framework client-side app (vanilla JS, jQuery, Alpine.js, Astro islands, etc).

import FaultScopeBrowser from '@faultscope/node/browser';

FaultScopeBrowser.init({
  dsn: 'https://your-hub.example.com/api/ingest/batch',
  apiKey: 'your-api-key',
  environment: 'production',
  debug: false,
});

// Auto-captures: window.onerror, unhandledrejection, beforeunload

// Manual capture
FaultScopeBrowser.captureException(new Error('Something broke'));
FaultScopeBrowser.captureMessage('User clicked deprecated button', 'warning');

// User context (merged into all events)
FaultScopeBrowser.setUser({ id: 42, email: 'user@example.com' });

// Breadcrumbs
FaultScopeBrowser.addBreadcrumb({
  category: 'navigation',
  message: 'User navigated to /dashboard',
  level: 'info',
});

// Flush manually
FaultScopeBrowser.flush();

API Reference

Server SDK (@faultscope/node)

Function Description
init(opts) Initialize with DSN and API key
captureException(err, extra?) Capture an error or thrown value
captureProfile(profile) Send a performance profile
flushBuffer() Flush all buffered events immediately
expressErrorHandler() Express error handler middleware
fastifyPlugin(fastify, opts, done) Fastify plugin

Browser SDK (@faultscope/node/browser)

Function Description
init(opts) Initialize with DSN and API key
captureException(err, extra?) Capture an error
captureMessage(msg, level?, extra?) Capture a plain message
addBreadcrumb(crumb) Add a breadcrumb to the trail
setUser(user) Set user context
clearUser() Clear user context
flushBuffer() Flush all buffered events

InitOptions (Server)

{
  dsn: string;         // Required: FaultScope ingest URL
  apiKey?: string;     // Required: API key (also accepts `key`)
  key?: string;        // Alias for apiKey
  environment?: string; // Default: NODE_ENV
  release?: string;    // Default: APP_VERSION env var
  debug?: boolean;     // Default: false
}

BrowserInitOptions

{
  dsn: string;           // Required
  apiKey: string;        // Required
  environment?: string;  // Default: 'production'
  release?: string;
  debug?: boolean;
  maxBreadcrumbs?: number; // Default: 50
}

# 1. Build and link the SDK globally
cd platform/sdk/node
npm run build
npm link

# 2. Install in your Next.js / other project
cd your-nextjs-project
npm link @faultscope/node

# 3. After making changes to the SDK, rebuild
cd platform/sdk/node
npm run build   # or: npm run dev (watch mode)

Tip: Run npm run dev in the SDK folder for auto-rebuild on save while developing.


License

MIT

Related Packages

@allturko/nabiz-node

Nabız Hub için Node.js raporlayıcı — sunucu hataları, SSR hataları, yavaş istekl...

1,336 0
@watchforge/browser

WatchForge JavaScript SDK: automatic error, log and performance capture for brow...

5,289
routeman-cli

Generate a complete Postman collection from your Node.js, Bun or Deno API (Expre...

370 0
@easy-cms/core

Embedded, code-first headless CMS for Nuxt and Next.js

25,029 2
@metigan/forms

Embed Metigan forms anywhere: a framework-free core, a DOM renderer, React and V...

299

Version History

Version Released License
1.1.0 MIT