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

@smart-dev-agency/smart-grow-logs

v2.0.0

Published

Smart Grow Logs - Secure logging SDK for web applications.

Readme

Smart Grow Logs - Web SDK

Smart Grow Logs for the web sends encrypted logs from browser apps and can automatically capture uncaught browser errors.

What This SDK Is For

Use this SDK if you want to:

  • send logs from React, Vue, Vite or plain browser apps
  • attach metadata such as user, session or domain context
  • capture uncaught browser errors automatically
  • capture unhandled promise rejections automatically

Before You Start

You need:

  1. A Smart Grow Logs project.
  2. An API key.
  3. Your ingestion URL.

Installation

npm install @smart-dev-agency/smart-grow-logs

Or with your preferred package manager:

yarn add @smart-dev-agency/smart-grow-logs
pnpm add @smart-dev-agency/smart-grow-logs

Quick Start

import { LogLevel, SmartGrowLogs } from '@smart-dev-agency/smart-grow-logs';

await SmartGrowLogs.initialize({
  apiKey: 'sgl_your_api_key',
  baseUrl: 'https://logs-api.smart-grow.app/',
  debug: true,
  autoCaptureEnabled: true,
});

await SmartGrowLogs.info('Application started');

await SmartGrowLogs.sendLog({
  level: LogLevel.Error,
  message: 'Checkout failed',
  stackTrace: new Error().stack,
  metadata: {
    orderId: 'ORD-123',
    step: 'payment',
  },
  userIdentifier: '[email protected]',
  sessionId: 'session-abc-123',
});

Common Use Cases

1. Log a User Action

await SmartGrowLogs.info('User opened billing page');

2. Log a Caught Error

try {
  await api.checkout();
} catch (error) {
  const err = error as Error;

  await SmartGrowLogs.error(err.message, {
    stackTrace: err.stack,
    metadata: {
      feature: 'checkout',
    },
  });
}

3. Log With Business Metadata

await SmartGrowLogs.warn('Payment retry scheduled', {
  metadata: {
    orderId: 'ORD-123',
    retry: 2,
    provider: 'stripe',
  },
  userIdentifier: '[email protected]',
});

Auto-Capture

With autoCaptureEnabled: true, the SDK registers:

  • window.error
  • unhandledrejection

What Is Captured Today

All auto-captured errors are sent at fatal level.

  • uncaught browser errors
  • unhandled promise rejections

What Is Not Captured Automatically

  • framework boundaries that catch the error before it reaches the browser globals
  • errors you swallow manually in your own try/catch

If your framework catches the error first, forward it manually.

Framework Examples

React

Initialize once during startup:

import { SmartGrowLogs } from '@smart-dev-agency/smart-grow-logs';

export async function initLogger() {
  await SmartGrowLogs.initialize({
    apiKey: import.meta.env.VITE_SMARTGROW_API_KEY,
    baseUrl: import.meta.env.VITE_SMARTGROW_URL,
    debug: import.meta.env.DEV,
  });
}

Forward boundary errors manually:

componentDidCatch(error: Error, info: React.ErrorInfo) {
  void SmartGrowLogs.error(error.message, {
    stackTrace: error.stack,
    metadata: {
      source: 'react-error-boundary',
      componentStack: info.componentStack,
    },
  });
}

Vue

import { SmartGrowLogs } from '@smart-dev-agency/smart-grow-logs';

await SmartGrowLogs.initialize({
  apiKey: import.meta.env.VITE_SMARTGROW_API_KEY,
  baseUrl: import.meta.env.VITE_SMARTGROW_URL,
});

app.config.errorHandler = (error, instance, info) => {
  void SmartGrowLogs.error(String(error), {
    metadata: {
      source: 'vue-error-handler',
      info,
    },
  });
};

API Essentials

Main entry points:

  • SmartGrowLogs.initialize(options)
  • SmartGrowLogs.sendLog(options)
  • SmartGrowLogs.debug(...)
  • SmartGrowLogs.info(...)
  • SmartGrowLogs.warn(...)
  • SmartGrowLogs.error(...)
  • SmartGrowLogs.fatal(...)

Important option fields:

  • apiKey
  • baseUrl
  • debug
  • autoCaptureEnabled

Important log fields:

  • level
  • message
  • stackTrace
  • metadata
  • userIdentifier
  • sessionId

Auto-Detected Fields

The SDK sends browser and device context automatically, including:

  • device_type
  • os_name
  • os_version
  • app_version
  • browser_name
  • browser_version
  • screen_width
  • screen_height
  • language
  • timezone

App Version Detection

The SDK tries these sources, in this order:

  1. <meta name="version" content="1.0.0">
  2. <meta name="app-version" content="1.0.0">
  3. window.APP_VERSION
  4. window.__APP_VERSION__

Example:

<meta name="version" content="1.2.3" />

Server-Side Rendering (SSR)

When using frameworks like Next.js or Nuxt 3, code runs on both server and client. The SDK is browser-only — initialize it only on the client side.

Next.js App Router

// app/providers.tsx
'use client';
import { useEffect } from 'react';
import { SmartGrowLogs } from '@smart-dev-agency/smart-grow-logs';

export function LoggerProvider({ children }: { children: React.ReactNode }) {
  useEffect(() => {
    SmartGrowLogs.initialize({
      apiKey: process.env.NEXT_PUBLIC_SMARTGROW_API_KEY!,
      baseUrl: process.env.NEXT_PUBLIC_SMARTGROW_URL!,
    });
  }, []);
  return <>{children}</>;
}

Nuxt 3

// plugins/smart-grow-logs.client.ts  ← the .client suffix ensures browser-only
import { SmartGrowLogs } from '@smart-dev-agency/smart-grow-logs';

export default defineNuxtPlugin(async () => {
  await SmartGrowLogs.initialize({
    apiKey: useRuntimeConfig().public.smartgrowApiKey,
    baseUrl: useRuntimeConfig().public.smartgrowUrl,
  });
});

SDK Lifecycle

For SPAs that need to re-initialize (e.g. after authentication changes), call destroy() before re-initializing to prevent duplicate event listeners:

SmartGrowLogs.destroy();
await SmartGrowLogs.initialize({ apiKey: '...', baseUrl: '...' });

Known Limitations

The following error sources are not captured automatically by the SDK:

| Source | Captured? | Workaround | |--------|-----------|------------| | Web Workers | No | Forward errors manually via postMessage or listen to worker.onerror | | Cross-origin iframes | No | Same-origin policy prevents parent from seeing iframe errors | | Third-party scripts (CORS) | Partial | Stack trace may be sanitized; only "Script error." is visible | | Promise.reject() with circular object | Yes (stringified with String()) | No action needed | | React / Vue component errors | No (framework catches first) | Use componentDidCatch or app.config.errorHandler — see Framework Examples |

Web Worker errors

To capture errors from a Worker, forward them to the main thread:

// In your worker file
self.onerror = (event) => {
  self.postMessage({ type: 'worker-error', message: event.message, stack: '' });
};

// In main thread
worker.addEventListener('message', (e) => {
  if (e.data.type === 'worker-error') {
    void SmartGrowLogs.error(e.data.message, { stackTrace: e.data.stack });
  }
});

Troubleshooting

Browser errors are captured, but React or Vue component errors are not

That is expected if your framework catches them first. Forward them manually from your framework boundary or handler.

I want full manual control over global errors

Disable automatic capture:

await SmartGrowLogs.initialize({
  apiKey: 'sgl_your_api_key',
  baseUrl: 'https://logs-api.smart-grow.app/',
  autoCaptureEnabled: false,
});

Browser Support

  • Chrome 87+
  • Firefox 78+
  • Safari 14+
  • Edge 88+

Requires WebAssembly support.

License

MIT