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

@bricksworks/sdk

v0.4.1

Published

Browser SDK for AI-interpretable event tracking and retention

Readme

@bricksworks/sdk

Browser SDK for AI-interpretable event tracking and session recording.

npm version License: MIT

Features

  • Click Tracking - Capture user clicks with element fingerprinting
  • Form Tracking - Track form submissions (without field values for privacy)
  • Navigation Tracking - Monitor page navigation including SPA transitions
  • Session Recording - Record DOM state for replay
  • Exception Capture - Track unhandled errors and promise rejections
  • Network Error Capture - Monitor failed HTTP requests (4xx, 5xx, network failures)
  • Rage Click Detection - Detect frustrated rapid clicking on the same element
  • Dead Click Detection - Find broken UI elements that don't respond to clicks
  • Element Fingerprinting - Reliable element identification in minified React apps
  • React Integration - First-class React provider and hooks
  • Privacy-First - No field values captured by default

Installation

npm install @bricksworks/sdk
# or
pnpm add @bricksworks/sdk
# or
yarn add @bricksworks/sdk

Quick Start

import { createBricks } from '@bricksworks/sdk';

const sdk = createBricks({
  apiKey: 'your-workspace-api-key',
});

sdk.start();

// After user logs in, identify them
sdk.identify('user-123', {
  email: '[email protected]',
  name: 'John Doe',
});

That's it! The SDK automatically tracks clicks, forms, navigation, and records sessions.

User Identification

Important: Call identify() after your user logs in to link their session to their identity. This enables personalized AI insights and cross-session tracking.

// Basic identification with user ID and traits
sdk.identify('user-123', {
  email: '[email protected]',
  name: 'John Doe',
});

// With additional business context
sdk.identify('user-123', {
  email: '[email protected]',
  name: 'John Doe',
  plan: 'pro',
  company: 'Acme Inc',
  role: 'admin',
});

// Anonymous traits (no user ID)
sdk.identify({
  email: '[email protected]',
});

When to Call Identify

  • After login - As soon as you know who the user is
  • After signup - Link the new user to their browsing session
  • On page load - If user is already authenticated, identify them immediately
// Example: React login flow
async function handleLogin(credentials) {
  const user = await api.login(credentials);

  // Identify user after successful login
  sdk.identify(user.id, {
    email: user.email,
    name: user.name,
    plan: user.subscription.plan,
  });
}

Full Example

import { createBricks } from '@bricksworks/sdk';

const sdk = createBricks({
  apiKey: 'your-workspace-api-key',
});

sdk.start();

// Identify user after login
sdk.identify({
  externalId: 'user-123',
  email: '[email protected]',
  plan: 'pro',
});

// Complete session when user finishes (e.g., checkout complete)
await sdk.complete();

React Integration

For React applications, use the provider and hook for a more idiomatic experience:

Setup

import { BricksProvider } from '@bricksworks/sdk/react';
import { ENDPOINTS } from '@bricksworks/sdk';

function App() {
  return (
    <BricksProvider
      apiKey="your-workspace-api-key"
      endpoint={ENDPOINTS.local} // optional, defaults to production
      debug={true}               // optional
    >
      <YourApp />
    </BricksProvider>
  );
}

Using the Hook

import { useBricks } from '@bricksworks/sdk/react';

function UserProfile({ userId }) {
  const bricks = useBricks();

  useEffect(() => {
    bricks.identify({ externalId: userId });
  }, [userId]);

  return <div>...</div>;
}

Provider Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | apiKey | string | required | Your workspace API key | | endpoint | string | production | Backend URL | | debug | boolean | false | Enable debug logging | | compression | boolean | true | Gzip compress payloads | | sessionTimeout | number | 30 min | Session timeout in ms | | plugins | object | all enabled | Plugin configuration | | onError | function | - | Error callback | | fallback | ReactNode | - | Error boundary fallback |

Requirements

  • React 16.8+ (hooks support required)
  • React is an optional peer dependency (not required for vanilla JS usage)

SSR Considerations

The React provider is client-only. For SSR frameworks like Next.js:

// Next.js App Router - mark as client component
'use client';

import { BricksProvider } from '@bricksworks/sdk/react';

export function Providers({ children }) {
  return (
    <BricksProvider apiKey="your-api-key">
      {children}
    </BricksProvider>
  );
}
// Next.js Pages Router - use dynamic import
import dynamic from 'next/dynamic';

const BricksProvider = dynamic(
  () => import('@bricksworks/sdk/react').then((mod) => mod.BricksProvider),
  { ssr: false }
);

Configuration

createBricks(config)

| Option | Type | Default | Description | |--------|------|---------|-------------| | apiKey | string | required | Your workspace API key | | endpoint | string | production | Backend URL (use ENDPOINTS.local for dev) | | debug | boolean | false | Enable debug logging to console | | compression | boolean | true | Gzip compress payloads | | sessionTimeout | number | 30 min | Session timeout in milliseconds |

Endpoints

import { createBricks, ENDPOINTS } from '@bricksworks/sdk';

// Production (default)
createBricks({ apiKey: '...' });

// Local development
createBricks({
  apiKey: '...',
  endpoint: ENDPOINTS.local,
});

Plugins

All plugins are enabled by default. You can disable or configure individual plugins:

const sdk = createBricks({
  apiKey: 'your-api-key',
  plugins: {
    // Disable a plugin
    recording: false,

    // Configure a plugin
    deadClick: {
      waitTimeMs: 3000,
      ignoreSelectors: ['.no-dead-click'],
    },
  },
});

Available Plugins

| Plugin | Description | Default | |--------|-------------|---------| | recording | Session recording with rrweb | enabled | | clickCapture | Click event tracking | enabled | | formCapture | Form submission tracking | enabled | | navigationCapture | Page navigation tracking | enabled | | exceptionCapture | Unhandled error tracking | enabled | | networkErrorCapture | Failed HTTP request tracking | enabled | | rageClick | Rapid click detection | enabled | | deadClick | Unresponsive element detection | enabled | | performance | Performance metrics | enabled |

Plugin Options

recording

plugins: {
  recording: {
    blockSelector: '.sensitive',      // CSS selector for elements to block
    maskInputSelector: 'input[type="password"]',
    maskAllInputs: true,              // Mask all input values (default: true)
  },
}

deadClick

Detects clicks on interactive elements (buttons, links, etc.) that don't cause any DOM changes within a timeout period. Uses MutationObserver to watch for DOM mutations after clicks.

plugins: {
  deadClick: {
    waitTimeMs: 2500,                 // Time to wait for DOM mutation (default: 2500ms)
    ignoreSelectors: ['.external'],   // CSS selectors to ignore
  },
}

How it works:

  1. User clicks an interactive element (button, link, element with role="button", etc.)
  2. SDK watches for any DOM changes using MutationObserver
  3. If no changes occur within waitTimeMs, it's flagged as a dead click
  4. Links that navigate away and clicks with modifier keys (Ctrl, etc.) are ignored

rageClick

Detects rapid, frustrated clicking on the same element.

plugins: {
  rageClick: {
    clickThreshold: 3,                // Clicks needed to trigger (default: 3)
    timeWindowMs: 1000,               // Time window in ms (default: 1000)
    radiusPixels: 30,                 // Max distance between clicks (default: 30)
  },
}

networkErrorCapture

Tracks failed HTTP requests from both fetch and XMLHttpRequest.

plugins: {
  networkErrorCapture: {
    urlPatterns: ['/api/'],           // Only track URLs matching these patterns
    minStatus: 400,                   // Minimum status code to capture (default: 400)
    captureNetworkFailures: true,     // Capture network failures (default: true)
  },
}

exceptionCapture

Tracks unhandled errors and promise rejections.

plugins: {
  exceptionCapture: {
    captureUnhandledErrors: true,     // Capture window.onerror (default: true)
    captureUnhandledRejections: true, // Capture unhandledrejection (default: true)
  },
}

SDK Methods

.start()

Start capturing events.

sdk.start();

.stop()

Stop capturing events.

sdk.stop();

.identify(params)

Identify the current user. Call after login.

sdk.identify({
  externalId: 'user-123',  // Your user ID
  email: '[email protected]',
  name: 'John Doe',
  plan: 'pro',
  company: 'Acme Inc',
});

// Or just traits without externalId
sdk.identify({ email: '[email protected]' });

.flush()

Force send any buffered events immediately.

await sdk.flush();

.complete()

Complete the session and notify the backend. Call when the user completes their journey (e.g., after checkout).

await sdk.complete();

.resetSession()

Start a new session. Returns the new session ID.

const newSessionId = sdk.resetSession();

.getSessionId()

Get the current session ID.

const sessionId = sdk.getSessionId();

.destroy()

Completely destroy the SDK and release all resources.

sdk.destroy();

Element Fingerprinting

The SDK uses multi-layer element identification to reliably track elements even in minified React applications:

  1. Data attributes (priority): data-testid, data-analytics-id
  2. ARIA: aria-label, aria-labelledby
  3. Semantics: id, name, href, type
  4. Content: element text
  5. Structure: DOM path

Tip: Add data-testid attributes to important elements for the most reliable tracking:

<button data-testid="checkout-button">Complete Purchase</button>

TypeScript Support

Full TypeScript support with exported types:

import type { BricksConfig, BricksInstance } from '@bricksworks/sdk';

// React types
import type { BricksProviderProps, BricksContextValue } from '@bricksworks/sdk/react';

Browser Support

  • Chrome 80+
  • Firefox 78+
  • Safari 14+
  • Edge 80+

Bundle Size

~150KB gzipped (includes session recording capabilities)

License

MIT