npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@kodeme-io/next-core-monitoring

v0.8.4

Published

Error tracking, monitoring, and observability for Next.js + Odoo applications

Readme

@kodeme-io/next-core-monitoring

Error tracking, monitoring, and observability for Next.js + Odoo applications

Production-grade monitoring solution with Sentry integration, Error Boundaries, structured logging, and performance tracking.

Features

  • Error Tracking - Sentry integration for client, server, and edge runtimes
  • Error Boundaries - React Error Boundaries to prevent white screens
  • Structured Logging - Production-safe logging with levels and context
  • Session Replay - See exactly what users did before errors
  • Performance Monitoring - Track Web Vitals and API response times
  • User Context - Know which users are affected by errors
  • Breadcrumbs - See the trail of events leading to errors
  • Source Maps - Readable stack traces in production
  • Zero Config - Works out of the box with sensible defaults

Installation

pnpm add @kodeme-io/next-core-monitoring
# or
npm install @kodeme-io/next-core-monitoring
# or
yarn add @kodeme-io/next-core-monitoring

Quick Start (5 minutes)

1. Get Sentry DSN

Sign up at sentry.io (free tier available) and get your DSN.

2. Add Environment Variables

# .env.local
NEXT_PUBLIC_SENTRY_DSN=https://[email protected]/...
NEXT_PUBLIC_APP_VERSION=1.0.0

# Optional
NEXT_PUBLIC_LOG_LEVEL=warn  # debug, info, warn, error, fatal
NEXT_PUBLIC_SENTRY_DEBUG=false

3. Initialize Monitoring

// src/app/layout.tsx
import { initMonitoring, ErrorBoundary } from '@kodeme-io/next-core-monitoring'

// Initialize once at app startup
initMonitoring({
  appName: 'my-app',
  version: process.env.NEXT_PUBLIC_APP_VERSION || '1.0.0',
  environment: process.env.NODE_ENV,
  getUserContext: () => {
    // Return current user info
    return {
      id: user?.id,
      email: user?.email,
      username: user?.name,
    }
  },
})

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <ErrorBoundary>
          {children}
        </ErrorBoundary>
      </body>
    </html>
  )
}

4. Add Sentry Config Files

// sentry.client.config.ts
import { initSentryClient } from '@kodeme-io/next-core-monitoring/sentry/client'

initSentryClient()
// sentry.server.config.ts
import { initSentryServer } from '@kodeme-io/next-core-monitoring/sentry/server'

initSentryServer()
// sentry.edge.config.ts
import { initSentryEdge } from '@kodeme-io/next-core-monitoring/sentry/edge'

initSentryEdge()

That's it! All errors are now being tracked.


Usage

Error Tracking

Automatic Error Capture

All unhandled errors are automatically captured:

  • React component errors
  • Unhandled Promise rejections
  • Console errors
  • Network errors
  • API errors

Manual Error Capture

import { captureClientException, captureClientMessage } from '@kodeme-io/next-core-monitoring'

try {
  await riskyOperation()
} catch (error) {
  captureClientException(error, {
    tags: { component: 'CustomerForm' },
    extra: { customerId: 123 }
  })
}

// Info/warning messages
captureClientMessage('Unusual user action', 'warning', {
  userId: 123,
  action: 'bulk-delete'
})

Error Boundaries

Component Error Boundary

import { ErrorBoundary } from '@kodeme-io/next-core-monitoring'

<ErrorBoundary fallback={<div>Something went wrong</div>}>
  <CustomerList />
</ErrorBoundary>

Route Error Boundary

import { RouteErrorBoundary } from '@kodeme-io/next-core-monitoring'

<RouteErrorBoundary>
  <Router />
</RouteErrorBoundary>

Chunk Loading Error Boundary

import { ChunkErrorBoundary } from '@kodeme-io/next-core-monitoring'

<ChunkErrorBoundary>
  <LazyComponent />
</ChunkErrorBoundary>

Custom Fallback

<ErrorBoundary
  fallback={(error, errorInfo) => (
    <div>
      <h1>Oops!</h1>
      <p>{error.message}</p>
      <button onClick={() => window.location.reload()}>
        Reload
      </button>
    </div>
  )}
>
  <MyComponent />
</ErrorBoundary>

Structured Logging

import { logger } from '@kodeme-io/next-core-monitoring'

// Basic logging
logger.debug('Debug info')
logger.info('User logged in', { userId: 123 })
logger.warn('High memory usage', { memory: 1024 })
logger.error('API failed', error, { endpoint: '/api/users' })
logger.fatal('Database connection lost', error)

// With context
const userLogger = logger.withContext({ userId: 123, requestId: 'abc' })
userLogger.info('Processing request')
// All logs will include userId and requestId

// Performance timing
logger.time('query')
const result = await database.query()
logger.timeEnd('query') // Logs: "query: 123ms"

User Context

import { setUser } from '@kodeme-io/next-core-monitoring'

// Set user after login
setUser({
  id: user.id,
  email: user.email,
  username: user.name
})

// Clear user on logout
setUser(null)

Breadcrumbs

import { addBreadcrumb } from '@kodeme-io/next-core-monitoring'

addBreadcrumb({
  message: 'User clicked submit button',
  category: 'ui',
  level: 'info',
  data: { formId: 'customer-form' }
})

Tags & Context

import { setTag, setContext } from '@kodeme-io/next-core-monitoring'

// Tags for grouping
setTag('feature', 'checkout')
setTag('version', '2.0.0')

// Custom context
setContext('customer', {
  id: 123,
  name: 'ACME Corp',
  plan: 'enterprise'
})

API Monitoring

import { withMonitoring } from '@kodeme-io/next-core-monitoring'

// Wrap API routes
export const GET = withMonitoring(
  async (request: Request) => {
    const data = await fetchData()
    return Response.json(data)
  },
  {
    name: 'GET /api/customers',
    tags: { api: 'customers' }
  }
)

React Hooks 🆕

useWebVitals - Performance Monitoring Hook

Track Core Web Vitals with automatic cleanup and scoring:

import { useWebVitals } from '@kodeme-io/next-core-monitoring'

function PerformanceDashboard() {
  const { metrics, ratings, score, grade } = useWebVitals({
    onMetric: (metric) => {
      if (metric.rating === 'poor') {
        // Show performance warning
        showPerformanceWarning(metric)
      }
    },
    onLCPCollect: (metric) => {
      // Track loading performance
      analytics.track('LCP', { value: metric.value, rating: metric.rating })
    }
  })

  return (
    <div>
      <h2>Performance Score: {score}/100 (Grade: {grade})</h2>
      <div>LCP: {metrics.get('LCP')?.value}ms ({ratings.LCP})</div>
      <div>FID: {metrics.get('FID')?.value}ms ({ratings.FID})</div>
      <div>CLS: {metrics.get('CLS')?.value} ({ratings.CLS})</div>
    </div>
  )
}

useLogger - Component Logging Hook

Structured logging with automatic component context:

import { useLogger } from '@kodeme-io/next-core-monitoring'

function UserProfile({ userId }: { userId: string }) {
  const { logger, info, error } = useLogger({
    componentName: 'UserProfile',
    context: { userId },
    logLifecycle: true, // Log mount/unmount
    trackPerformance: true // Track render performance
  })

  const [user, setUser] = useState(null)

  useEffect(() => {
    logger.time('fetch-user')
    fetchUser(userId)
      .then(setUser)
      .catch(err => error('Failed to fetch user', err))
      .finally(() => logger.timeEnd('fetch-user'))
  }, [userId])

  return <div>{user?.name}</div>
}

useErrorBoundary - Error Handling Hook

Error boundary with automatic recovery and error counting:

import { useErrorBoundary } from '@kodeme-io/next-core-monitoring'

function RiskyComponent() {
  const { error, ErrorBoundary, reset, errorCount } = useErrorBoundary({
    onError: (error, errorInfo) => {
      analytics.track('component_error', {
        component: 'RiskyComponent',
        error: error.message
      })
    },
    maxErrors: 3,
    autoResetDelay: 5000,
    context: { feature: 'user-management' }
  })

  if (error) {
    return (
      <div>
        <p>Something went wrong (Error #{errorCount})</p>
        <button onClick={reset}>Try Again</button>
      </div>
    )
  }

  return (
    <ErrorBoundary>
      <ComponentThatMightFail />
    </ErrorBoundary>
  )
}

useMonitoring - All-in-One Hook

Complete monitoring setup with Web Vitals, logging, and error boundaries:

import { useMonitoring } from '@kodeme-io/next-core-monitoring'

function App({ user }: { user: User | null }) {
  const monitoring = useMonitoring({
    componentName: 'App',
    user,
    context: { version: '1.0.0', environment: process.env.NODE_ENV },
    tags: { feature: 'main-app' },
    webVitals: {
      onMetric: (metric) => {
        if (metric.rating === 'poor') {
          // Show performance notification
        }
      }
    },
    logger: {
      logLifecycle: true,
      trackPerformance: true
    },
    errorBoundary: {
      maxErrors: 3,
      onError: (error, errorInfo) => {
        // Custom error handling
      }
    }
  })

  const { ErrorBoundary } = monitoring.errorBoundary

  return (
    <ErrorBoundary>
      <YourAppContent />
    </ErrorBoundary>
  )
}

Testing 🆕

Comprehensive test suite with Jest and React Testing Library:

# Run all tests
pnpm test

# Run tests in watch mode
pnpm test:watch

# Run tests with coverage
pnpm test:coverage

Test Examples

// Example test for useLogger hook
import { renderHook } from '@testing-library/react'
import { useLogger } from '@kodeme-io/next-core-monitoring'

describe('useLogger', () => {
  it('should create logger with component context', () => {
    const { result } = renderHook(() =>
      useLogger({
        componentName: 'TestComponent',
        context: { testId: '123' }
      })
    )

    expect(result.current.logger).toBeDefined()
    expect(typeof result.current.info).toBe('function')
  })
})

Testing 🆕

This package includes a comprehensive test suite covering:

  • Unit Tests - All core modules, hooks, and utilities
  • Integration Tests - React hooks and error boundaries
  • Mocking - Complete test setup with Jest mocks
  • Coverage - High test coverage for production reliability

Test Structure

src/__tests__/
├── setup.ts                 # Test configuration and mocks
├── config.test.ts           # Configuration module tests
├── logger.test.ts           # Logger functionality tests
├── sentry.test.ts           # Sentry integration tests
├── interceptors.test.ts     # API interceptor tests
├── performance.test.ts      # Performance monitoring tests
├── error-boundaries.test.tsx # Error boundary component tests
└── hooks.test.tsx           # React hooks tests

Running Tests

# Install dependencies
pnpm install

# Run all tests
pnpm test

# Run tests with coverage report
pnpm test:coverage

# Run tests in watch mode during development
pnpm test:watch

Test Configuration

  • Framework: Jest with React Testing Library
  • Environment: JSDOM for React component testing
  • Mocking: Comprehensive mocks for Sentry, Performance API, and browser APIs
  • Coverage: Configured for high coverage thresholds

Configuration

Environment Variables

# Required
NEXT_PUBLIC_SENTRY_DSN=https://[email protected]/...

# Optional
NEXT_PUBLIC_APP_VERSION=1.0.0
NEXT_PUBLIC_LOG_LEVEL=warn          # debug, info, warn, error, fatal
NEXT_PUBLIC_SENTRY_DEBUG=false      # Enable debug logging
NEXT_PUBLIC_SENTRY_TRACES_SAMPLE_RATE=0.1          # 10% of transactions
NEXT_PUBLIC_SENTRY_REPLAYS_SESSION_SAMPLE_RATE=0.1 # 10% of sessions
NEXT_PUBLIC_SENTRY_REPLAYS_ON_ERROR_SAMPLE_RATE=1.0 # 100% of errors

Advanced Configuration

import { initMonitoring } from '@kodeme-io/next-core-monitoring'

initMonitoring({
  appName: 'my-app',
  version: '1.0.0',
  environment: 'production',

  // Sentry configuration
  sentry: {
    enabled: true,
    dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
    tracesSampleRate: 0.1,
    replaysSessionSampleRate: 0.1,
    replaysOnErrorSampleRate: 1.0,
  },

  // Logger configuration
  logger: {
    enabled: true,
    level: LogLevel.WARN,
    console: false, // Disable console in production
  },

  // User context provider
  getUserContext: () => {
    const user = getCurrentUser() // Your auth function
    if (!user) return null

    return {
      id: user.id,
      email: user.email,
      username: user.name,
      // Add custom fields
      role: user.role,
      plan: user.subscription?.plan,
    }
  },
})

Best Practices

1. Always Use Error Boundaries

// ❌ Bad - no error boundary
<CustomerList />

// ✅ Good - wrapped in error boundary
<ErrorBoundary>
  <CustomerList />
</ErrorBoundary>

2. Add Context to Errors

// ❌ Bad - no context
throw new Error('Failed to save')

// ✅ Good - with context
captureClientException(error, {
  tags: { feature: 'customer-management' },
  extra: { customerId, formData }
})

3. Use Structured Logging

// ❌ Bad - console.log
console.log('User logged in:', userId)

// ✅ Good - structured logger
logger.info('User logged in', { userId, timestamp: Date.now() })

4. Set User Context Early

// In your auth callback
async function onLogin(user) {
  setUser({
    id: user.id,
    email: user.email,
    username: user.name
  })

  // Now all errors will include user info
}

5. Use Breadcrumbs for User Actions

function handleFormSubmit() {
  addBreadcrumb({
    message: 'User submitted customer form',
    category: 'form',
    data: { formId: 'customer-form', fields: Object.keys(formData) }
  })

  // Submit form...
}

Sentry Setup

1. Create Account

Go to sentry.io and create an account (free tier available).

2. Create Project

  1. Click "Create Project"
  2. Select "Next.js"
  3. Copy your DSN

3. Configure Alerts

  1. Go to Project Settings → Alerts
  2. Create alert rules:
    • "New error occurs" → Notify via Slack/Email
    • "Error rate exceeds threshold" → Notify team

4. Set Up Source Maps

Add to next.config.js:

const { withSentryConfig } = require('@sentry/nextjs')

module.exports = withSentryConfig(
  {
    // Your Next.js config
  },
  {
    // Sentry webpack plugin options
    silent: true,
    org: 'your-org',
    project: 'your-project',
  },
  {
    // Upload source maps on build
    hideSourceMaps: true,
    disableLogger: true,
  }
)

Troubleshooting

Errors Not Showing in Sentry

  1. Check DSN is correct
  2. Check environment variables are set
  3. Check browser console for Sentry errors
  4. Enable debug mode: NEXT_PUBLIC_SENTRY_DEBUG=true

Source Maps Not Working

  1. Ensure withSentryConfig is in next.config.js
  2. Set SENTRY_AUTH_TOKEN environment variable
  3. Run build: pnpm build
  4. Check Sentry dashboard → Settings → Source Maps

Logs Not Appearing

  1. Check log level: NEXT_PUBLIC_LOG_LEVEL
  2. Check console transport is enabled
  3. Check browser console is not filtered

Cost

Sentry Free Tier

  • 5,000 errors/month
  • 1 user
  • 30-day retention
  • Cost: $0

Sentry Team Plan (Recommended)

  • 50,000 errors/month
  • 50,000 performance transactions/month
  • 500 session replays/month
  • Unlimited users
  • 90-day retention
  • Cost: $26/month

For Multiple Apps

  • ~8,333 errors/month per app (6 apps)
  • Still fits in Team plan
  • Total: $26/month

Examples

See docs/examples/monitoring/ for complete examples:

  • Basic setup
  • Custom error handling
  • API monitoring
  • Performance tracking

License

MIT


Support