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 🙏

© 2025 – Pkg Stats / Ryan Hefner

userpath-js

v1.1.1

Published

UserPath is a privacy-focused analytics tool that serves as an alternative to Google Analytics. It's built with a focus on reliability, performance, and data privacy. The platform offers first-party integration capabilities, allowing you to collect and an

Readme

UserPath Client SDK

UserPath is a privacy-focused analytics tool that serves as an alternative to Google Analytics. It's built with a focus on reliability, performance, and data privacy. The platform offers first-party integration capabilities, allowing you to collect and analyze user data directly from your own servers without external dependencies, resulting in more accurate and comprehensive insights.

Installation

npm install userpath-js

Usage

UserPath can be used both in the browser and server in different contexts.

NPM

In a browser environment, you can import the UserPath class and initialize it with your app ID and base URL. The library will automatically start tracking events and send them to the server as soon as you initialize it.

// file: src/userpath.ts
import { UserPath } from 'userpath-js';

const up = new UserPath({
	appId: 'my-app-id',
	serverUrl: 'https://my-userpath-domain.com/events', // Optional
	version: 1,
	flushIntervalMs: 5000, // Optional: Time in milliseconds between event batch sends (default: 5000)
});

export { up };
// file: src/pricing.ts
import { up } from './userpath';

// Tracking is already initialized and running
// You can track custom events like this:
up.track('purchase', {
	price: 42,
	amount: 10,
	currency: 'USD',
	properties: {
		product_id: '123',
		product_name: 'Product 1',
	},
});

Browser

Alternatively, you can include the UserPath Pixel using a script tag in your HTML file. This will automatically initialize the client and start tracking events. You can also track custom events using the exposed userpath object in the global scope.

<!-- index.html -->
<script
	src="https://my-userpath-domain.com/events/v1/px.js"
	data-app="my-app-id"
></script>
// index.js
const up = window.userpath;
up.track('purchase', {
	price: 42,
	amount: 10,
	currency: 'USD',
});

Server Integration

In order to avoid privacy-first browsers and ad blockers, you can use the UserPath server integration to provide a first-party analytics solution. This will proxy all requests to the main UserPath server, so you can continue to use the client in the browser as usual without worrying about being blocked.

// file: src/index.ts
import { userpath } from 'userpath-js/server';

// Using Node.js
http
	.createServer(function (req, res) {
		return userpath.fetch(req);
	})
	.listen(3000);

// Using Bun
Bun.serve({
	fetch(req) {
		return userpath.fetch(req);
	},
});

// Using Elysia
const app = new Elysia({ name: 'my-userpath' });

app.get('/', () => 'Hello World from Elysia');

app.mount('/events', userpath.fetch); // Mount the UserPath server

app.listen(3000);

UserPath also provides easy and native integrations for the most popular server frameworks:

Automatic Event Tracking

When using the client in the browser, UserPath automatically tracks various user interactions without any additional configuration. Here's what gets tracked automatically, but you can also track custom events.

Form Interactions

Form Submissions (form_submit)

Tracks when users submit forms:

{
  name: 'form_submit',
  url: 'https://example.com/signup',
  referrer: 'https://example.com/home',
  properties: {
    form_name: 'signup-form', // Form name, id, or aria-label
    time_to_complete: 15000, // Time in milliseconds from first interaction to submission
  }
}

Text Input Fields (input_fill)

Tracks when users complete filling in text-based input fields. Events are only fired when:

  • The input value has actually changed
  • The new value is not empty
  • The user has finished editing (on blur)
{
  name: 'input_fill',
  url: 'https://example.com/signup',
  referrer: 'https://example.com/home',
  properties: {
    input_type: 'text', // text, email, number, etc.
    label: 'Full Name', // Input label or identifier
    form_name: 'signup-form', // If available
  }
}

Select Dropdowns (input_select)

Tracks when users select an option from dropdowns:

{
  name: 'input_select',
  url: 'https://example.com/checkout',
  referrer: 'https://example.com/cart',
  properties: {
    input_type: 'select',
    label: 'Country',
    option_label: 'United States',
    form_name: 'shipping-form',
  }
}

Radio Buttons (input_radio)

Tracks radio button selections:

{
  name: 'input_radio',
  url: 'https://example.com/profile',
  referrer: 'https://example.com/settings',
  properties: {
    input_type: 'radio',
    group: 'gender',
    label: 'Male',
    form_name: 'profile-form',
  }
}

Checkboxes (input_checkbox)

Tracks checkbox interactions:

{
  name: 'input_checkbox',
  url: 'https://example.com/preferences',
  referrer: 'https://example.com/signup',
  properties: {
    input_type: 'checkbox',
    label: 'Subscribe to newsletter',
    checked: true,
    form_name: 'preferences-form',
  }
}

Range Inputs (input_range)

Tracks range slider changes:

{
  name: 'input_range',
  url: 'https://example.com/settings',
  referrer: 'https://example.com/profile',
  properties: {
    input_type: 'range',
    label: 'Volume',
    form_name: 'settings-form',
  }
}

Click Tracking

Automatically tracks meaningful clicks on:

  • Buttons
  • Links
  • Interactive elements with labels
{
  name: 'click',
  url: 'https://example.com/form',
  referrer: 'https://example.com/home',
  properties: {
    label: 'Submit',
    element: 'button',
    id: 'submit-btn',
  }
}

Scroll Tracking

Tracks meaningful scroll depth on pages:

{
  name: 'scroll',
  url: 'https://example.com/blog/post',
  title: 'Blog Post Title',
  referrer: 'https://example.com'
}

Video Tracking

Automatically tracks video interactions for HTML5 video elements:

Video Play (video_play)

Tracks when a video starts playing:

{
  name: 'video_play',
  url: 'https://example.com/page',
  referrer: 'https://example.com',
  title: 'Introduction Video', // Video title if available
  properties: {
    duration: 180, // Total video duration in seconds
    current_time: 0, // Current playback position in seconds
    src: 'https://example.com/video.mp4',
    video_id: 'intro-video', // Video element ID if available
  }
}

Video Pause (video_pause)

Tracks when a video is paused:

{
  name: 'video_pause',
  url: 'https://example.com/page',
  referrer: 'https://example.com',
  title: 'Introduction Video',
  properties: {
    duration: 180,
    current_time: 45,
    watch_time: 45, // Time watched in this session in seconds
    src: 'https://example.com/video.mp4',
    video_id: 'intro-video',
  }
}

Video Complete (video_complete)

Tracks when a video playback completes:

{
  name: 'video_complete',
  url: 'https://example.com/page',
  referrer: 'https://example.com',
  title: 'Introduction Video',
  properties: {
    duration: 180,
    current_time: 180,
    watch_time: 180, // Total time watched in this session in seconds
    src: 'https://example.com/video.mp4',
    video_id: 'intro-video',
  }
}

Page Time Tracking

Automatically tracks how long users spend on pages, including active (visible) time:

User Activity Tracking

Automatically tracks user activity and inactivity periods:

User Inactive (user_inactive)

Tracks when a user becomes inactive (no mouse movement, keyboard input, or other interactions for 60 seconds):

{
  name: 'user_inactive',
  url: 'https://example.com/page',
  title: 'Page Title'
}

User Active (user_active)

Tracks when a user becomes active again after being inactive:

{
  name: 'user_active',
  properties: {
    inactive_duration: 75, // How long the user was inactive in seconds
    url: 'https://example.com/page',
    title: 'Page Title'
  }
}

Page View (page_view)

Tracks when a page is initially loaded:

{
  name: 'page_view',
  url: 'https://example.com/page',
  title: 'Page Title',
  referrer: 'https://example.com'
}

Page Visibility (page_visibility)

Tracks when users switch tabs or minimize the browser:

{
  name: 'page_visibility',
  url: 'https://example.com/page',
  title: 'Page Title',
  referrer: 'https://example.com',
  properties: {
    visible: true, // or false
    total_time: 120, // Total time since page load in seconds
    visible_time: 85 // Time the page was actually visible in seconds
  }
}

Page Exit (page_exit)

Tracks timing information when users leave the page:

{
  name: 'page_exit',
  url: 'https://example.com/page',
  title: 'Page Title',
  referrer: 'https://example.com',
  properties: {
    total_time: 300, // Total time spent on page in seconds
    visible_time: 240 // Time the page was actually visible in seconds
  }
}

Privacy Considerations

  • Password fields are never tracked
  • Only interaction events are tracked, not actual input values
  • Form submissions are tracked without capturing sensitive data
  • All tracking respects user privacy settings and GDPR compliance

Error Tracking

UserPath automatically captures uncaught errors and unhandled promise rejections in your application, providing valuable insights about JavaScript errors that users encounter.

Automatic Error Tracking

When enabled (on by default), the SDK will automatically capture:

  • Uncaught exceptions via the global error event
  • Unhandled promise rejections via the unhandledrejection event
{
  name: 'error',
  message: 'Cannot read property of undefined',
  stack: 'Error: Cannot read property of undefined\n    at button.onClick (app.js:42)',
  source: 'window.onerror',
  filename: 'app.js',
  lineno: 42,
  colno: 24
}

Manual Error Tracking

You can also manually track errors in try/catch blocks:

try {
	// Some code that might throw an error
	processUserPurchase();
} catch (error) {
	// Log the error to UserPath
	up.trackError(error, {
		context: 'purchase_flow',
		product_id: '123',
	});

	// Handle the error appropriately
	showErrorMessage();
}

Disabling Automatic Tracking Features

UserPath automatically tracks various user interactions, but you can customize which features are enabled:

// All tracking options are enabled by default
const up = new UserPath({
	appId: 'my-app-id',
	autoTrack: {
		errors: true, // Track JavaScript errors
		clicks: true, // Track clicks on buttons, links, etc.
		scrolling: true, // Track scroll depth
		forms: true, // Track form interactions and submissions
		videos: true, // Track video play/pause/end events
		pageVisibility: true, // Track page visibility and time spent
		inactivity: true, // Track user activity/inactivity
	},
});

You can disable any specific tracking feature individually:

const up = new UserPath({
	appId: 'my-app-id',
	autoTrack: {
		forms: false, // Disable form tracking
		videos: false, // Disable video tracking
	},
});

You can also disable error tracking after initialization:

up.uninstallErrorHandler();

And re-enable it later if needed:

up.installErrorHandler();

User Identification

There are several ways to identify users in UserPath:

Via Script Tag

You can add a data-user attribute to your script tag to identify users immediately:

<script
	src="https://api.userpath.co/v1/px.js"
	data-app="your-app-id"
	data-user="user123"
></script>

Via SDK

You can also identify users programmatically using the SDK:

// On initialization
const up = new UserPath({
	appId: 'your-app-id',
	userId: 'user123',
});

// Set user ID programmatically
up.setUserId('user123');

// Or with additional user information
up.identify({
	id: 'user123',
	email: '[email protected]',
	name: 'John Doe',
	properties: {
		plan: 'premium',
		signupDate: '2023-01-15',
	},
});

Retrieving User ID

You can get the current user ID:

const currentUserId = userpath.getUserId();

Questions

Got questions? We're here to help!

Email us at [email protected]

Configuration Options

When initializing the UserPath SDK, you can provide several configuration options:

| Option | Type | Default | Description | | ----------------- | ------ | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | | appId | string | (required) | Your UserPath application ID | | serverUrl | string | "https://api.userpath.co" | The base URL for the UserPath API | | version | number | 1 | API version to use | | userId | string | undefined | Optional user ID to associate with all events | | flushIntervalMs | number | 5000 | Time in milliseconds between event batch sends. Events are batched and sent in groups rather than individually to reduce server load. | | autoTrack | object | see below | Configuration for automatic event tracking |

Auto-tracking Configuration

// All tracking options are enabled by default
const up = new UserPath({
	appId: 'my-app-id',
	autoTrack: {
		errors: true, // Track JavaScript errors
		clicks: true, // Track clicks on buttons, links, etc.
		scrolling: true, // Track scroll depth
		forms: true, // Track form interactions and submissions
		videos: true, // Track video play/pause/end events
		pageVisibility: true, // Track page visibility and time spent
		inactivity: true, // Track user activity/inactivity
	},
});

You can disable any specific tracking feature individually:

const up = new UserPath({
	appId: 'my-app-id',
	autoTrack: {
		forms: false, // Disable form tracking
		videos: false, // Disable video tracking
	},
});

You can also disable error tracking after initialization:

up.uninstallErrorHandler();

And re-enable it later if needed:

up.installErrorHandler();

Geo location for first-party server integration

Connect your domain with CloudFlare, and then enable the managed transform for location headers:

Rules > Settings > Add visitor location headers Adds HTTP request headers with location information for the visitor's IP address, including city, country, continent, longitude, and latitude.

UserPath will use this information when saving events.