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

@dotcom-reliability-kit/client-metrics-web

v1.0.0

Published

A client for sending operational metrics to client metrics server from the web

Downloads

3,966

Readme

@dotcom-reliability-kit/client-metrics-web

A lightweight client for sending operational metrics events from the browser to the Customer Products Client Metrics Server. This module is part of FT.com Reliability Kit.

[!WARNING] This Reliability Kit module is intended for use in client-side JavaScript. Importing it into a Node.js app will result in errors being thrown.

[!IMPORTANT] Remember that this library is intended for sending operational metrics - metrics that help us understand whether your system is operating as expected. For analytics data you should still be using Spoor (or another solution common to your team).

Usage (systems)

Systems that want to send metrics from the client should import and construct a metrics client as part of their client-side JavaScript. If you're writing code that's shared across multiple systems do not import and construct a metrics client. See the usage guide for shared libraries.

Install @dotcom-reliability-kit/client-metrics-web as a dependency:

npm install --save @dotcom-reliability-kit/client-metrics-web

Include in your client-side code:

import { MetricsClient } from '@dotcom-reliability-kit/client-metrics-web';
// or
const { MetricsClient } = require('@dotcom-reliability-kit/client-metrics-web');

MetricsClient

The MetricsClient sends events to the Client Metrics Server, using POST to the following endpoint /api/v1/ingest.

The events are added to a batch. When the batch reaches its max capacity, which defaults to 20, the client sends the events to the server. If it does not reach that max capacity, the client sends the events every 10 seconds. This retentionPeriod is a configurable option (see options.retentionPeriod). If there are no events added to the batch, nothing is sent.

The correct environment (production vs test) is automatically selected based on the browser hostname. If your hostname has test, staging or local, the events will be sent to our test server. Else, it will send the metrics to the production server.

The class should only ever be constructed once or you'll end up sending duplicate metrics. You should construct the metrics client as early as possible in the loading of the page. For the required options, see configuration options.

const client = new MetricsClient({
    // Options go here
});

This will bind some global event handlers:

client.recordEvent()

Send a metrics event:

client.recordEvent('namespace.event', {
    // Any event details you want to send can go here as key/value pairs
});

The event namespace must be comprised of alphanumeric characters, underscores, and hyphens, possibly separated by periods. Other than the above, the event namespace is free-form for now. A later major version of the client may lock down the top-level namespace further.

client.enable()

Enable the client. This is called by default during instantiation but you may need to call this if the client is ever disabled.

client.enable();

client.disable()

Disable the client, preventing any metrics from being sent. Global event handlers are also unbound.

client.disable();

client.isEnabled

A boolean indicating whether the client is currently enabled.

client.isAvailable

A boolean indicating whether the client was correctly configured and set up. If this is false then it's not possible for events to be sent to AWS CloudWatch RUM.

Event-based API

Passing around a single client instance may not be easy or preferable in your system, depending on complexity. For this we also bind a listener on window for the ft.clientMetric event.

This allows you to send metric events from anywhere in your system, even if you don't have access to the client. You need to emit a custom event, either on window:

window.dispatchEvent(
    new CustomEvent('ft.clientMetric', {
        detail: {
            namespace: 'namespace.event',
            // Any event details you want to send can go here as key/value pairs
        }
    }
));

or from another element on the page, as long as you bubble the event:

const element = document.getElementById('my-component');
element.dispatchEvent(
    new CustomEvent('ft.clientMetric', {
        bubbles: true,
        detail: {
            namespace: 'namespace.event',
            // Any event details you want to send can go here as key/value pairs
        }
    }
));

When sending metrics in this way, the detail object can have any number of properties. These properties will be extracted into the final metrics event and sent to the client metrics server. For example:

window.dispatchEvent(
    new CustomEvent('ft.clientMetric', {
        detail: { namespace: 'snack.consumed', fruit: 'banana' }
    }
));

// is equivalent to:

client.recordEvent('snack.consumed', { fruit: 'banana' });

Error handling

If something goes wrong with the configuration of the metrics client or the sending of an event, we don't throw an error - this could result in an infinite loop where we try to record the thrown error and that throws another error.

Instead of throwing an error, we log a warning to the console. If you're not seeing metrics in AWS then check the browser console for these warnings. It's also a good idea to check for them in local development before pushing any changes.

Configuration options

Config options can be passed into the MetricsClient function as an object with any of the keys below.

new MetricsClient({
    // Config options go here
});

options.systemCode

Required String. The Biz Ops system code you're sending metrics for.

new MetricsClient({ systemCode: 'my-system' });

The system code has to be a combination of alphanumerical characters, possibly separated by hyphens.

[!IMPORTANT] If the systemCode is not set properly, the client will fail to be constructed and it will not be possible to send any events. Attempting to use recordEvent will fail and log a warning Client not initialised properly, cannot record an event.

options.systemVersion

Optional String. The version number of the currently running system, which helps us to spot issues in new versions. This could be a version number or a git commit hash. Defaults to 0.0.0.

new MetricsClient({ systemVersion: '1.2.3' });

options.environment

Optional Enum. Can be production or test. This is used to defined what server to send the metrics to. If not set, the client will use the hostname to best guess where to send the metrics. If your hostname has test, staging or local, the test server will be used. Else, we will send the metrics to production. If this does not work for your use case, use the environment option to override that behaviour.

new MetricsClient({ environment: 'production' });

options.batchSize

Optional number. This is how many events can be accumulated in the queue before the client send them to the server. The minimum size is 20 events, and if you try to set batchSize to a lower number, it will be ignore and the options will be set to be 20 events.

options.retentionPeriod

Optional number. This is the amount of seconds the client will wait before sending a batch of events. The minimum wait time is 10 seconds, and if you try to set retentionPeriod to a lower number, it will be ignored and the client will use 10 seconds.

new MetricsClient({ retentionPeriod: 15 });

[!NOTE] If the batch of event reaches its maximum size, the events are sent before reaching the end of the retentionPeriod.

options.queue

Optional Queue. Events are batched into a queue before being sent. By default, the client will use an InMemoryQueue. You can provide your own queue implementation (as long as it extends the base Queue class).

import { InMemoryQueue, MetricsClient } from '@dotcom-reliability-kit/client-metrics-web';

const myQueue = new InMemoryQueue({ capacity: 11 });
new MetricsClient({ queue: myQueue });
Queue interface

The Queue class defines the contract that all queue implementations must follow.

import { Queue } from '@dotcom-reliability-kit/client-metrics-web';

new Queue({ capacity: 11 })
Options

capacity (number, optional): Maximum number of items the queue can hold. The default is 10 000.

[!NOTE] The choice of 10000 events is calculated from the following: We want the batch of events to be 10MB at max. A heavy event is about 750 bytes.

Required methods

Subclasses must implement the following methods:

  • add(item): Add an item to the queue.
  • drop(count): Drop the oldest item(s) from the queue. The default is 1.
  • pull(count): Remove and return the first count items.
  • size (getter): Current number of items in the queue.
  • capacity (getter): Maximum queue capacity (implemented in base class).

Usage (shared libraries)

If you want to record operational metrics from another library that's shared between systems, do not install this module as a dependency. Instead you should rely solely on the event-based API.

This ensures that:

  • We don't end up with duplicate global event handlers
  • The system installing your library does not have to inject the metrics client and manage the instance
  • We don't end up with systems and libraries using different incompatible versions of the metrics client (dependency hell)

We recommend that your library decides on a top-level namespace that all other events live under. E.g.

my-library.success
my-library.failure

Usage (infrastructure)

As well as a client you'll need to add a namespace on the Client Metrics Server to send events to. You can set this up yourselves following the script in the repo. This should set you up to send logs to Splunk and metrics to CloudWatch. You can then use your CloudWatch metrics to create graphs and alerts in Grafana.

Contributing

See the central contributing guide for Reliability Kit.

License

Licensed under the MIT license. Copyright © 2025, The Financial Times Ltd.