CLI Analytics
You shipped a CLI tool. Do you know if anyone uses the deploy command? Or whether init fails on Windows? Most CLI authors operate blind. They publish a package, watch the download counter tick up, and hope for the best.
BetterMeter's Node SDK changes that. It tracks command invocations, error rates, and execution duration, all without collecting arguments, file paths, or any personal information. You get the adoption data you need to prioritize features, fix broken commands, and understand how developers actually use your tool.
Two lines to integrate
If your CLI is built with Commander.js, a single method call instruments every registered command. The SDK hooks into Commander's action handlers, captures timing and exit codes, and sends a lightweight event to BetterMeter, all without modifying your command implementations.
import { BetterMeter } from "@bettermeter/node";
const bm = new BetterMeter({
siteId: "my-cli",
apiKey: "bm_...",
});
// Wraps all commands automatically
bm.wrapCommander(program, { version: "1.0.0" });Not using Commander.js? The trackCommand() method works with any Node.js CLI: yargs, oclif, meow, or a hand-rolled argument parser. Pass the command name, duration, and exit code, and BetterMeter handles the rest.
What gets tracked
Every CLI invocation produces a single event with six structured fields. These fields give you a complete picture of how your tool is used without capturing anything sensitive.
What is never tracked
BetterMeter tracks structure, not content. The distinction matters: knowing that a user ran deploy --region is useful for product decisions. Knowing they ran deploy --region us-east-1 crosses into sensitive territory.
The following are never collected, stored, or transmitted:
- ✕ Flag values and command arguments
- ✕ File paths, directory names, and working directory
- ✕ Environment variables and their values
- ✕ IP addresses, usernames, or any personally identifiable information
- ✕ Command output, stdout, or stderr content
This follows the same telemetry principles used by Stripe CLI, Vercel CLI, and the Homebrew package manager. Developer trust is earned by collecting only what you need to make product decisions, and nothing more. When developers audit your telemetry code (and they will), they should find exactly what you promised.
Dashboard metrics
Your CLI analytics dashboard surfaces five core metrics, each designed to answer a specific product question.
- 01 Total invocations and unique callers with period-over-period change. Tells you whether adoption is growing or stalling
- 02 Top commands ranked by usage with error rate per command. Reveals which commands matter most and which are broken
- 03 Average execution duration per command. Flags performance regressions before users complain
- 04 Daily activity timeseries showing invocations and unique callers. Visualizes usage patterns and the impact of new releases
- 05 Success rate across all commands. A single number that tells you how reliable your CLI is in the wild
Who this is for
Open source CLI maintainers
You have download counts from npm, but downloads are not usage. BetterMeter shows you which commands are actually invoked, how often they fail, and which platforms your users run. Use this data to prioritize the commands that matter, deprecate the ones that don't, and write migration guides backed by real adoption numbers.
Internal tools teams
Your team ships internal CLIs for deployment, database management, or infrastructure provisioning. Without usage data, you're guessing which tools need investment and which can be retired. BetterMeter gives you concrete numbers to justify headcount, measure adoption after a migration, and identify commands that are silently failing for your colleagues.
DevOps teams measuring CI/CD pipeline health
Your CLI runs thousands of times a day in CI pipelines. BetterMeter segments CI traffic from interactive usage so you can track pipeline reliability separately. Spot failure rate spikes after a deploy, identify the slowest commands in your pipeline, and correlate CI errors with specific command versions.
Frequently asked questions
What CLI frameworks does BetterMeter support?
BetterMeter provides automatic instrumentation for Commander.js via the wrapCommander() method, which hooks into every registered command with zero manual effort. For any other Node.js CLI framework (yargs, oclif, meow, or a hand-rolled arg parser), you can use the manual trackCommand() method to send events for each invocation. The SDK is framework-agnostic at its core; Commander.js simply gets the convenience wrapper.
Does it work in CI/CD environments?
Yes. BetterMeter auto-detects CI environments by checking for standard environment variables like CI, GITHUB_ACTIONS, GITLAB_CI, CIRCLECI, and JENKINS_URL. When a CI environment is detected, the event is tagged with ci: true so you can segment pipeline usage from interactive developer usage in your dashboard. No extra configuration is required.
What about user privacy?
Only the structural shape of commands is tracked: command names and flag names. Argument values, flag values, file paths, environment variables, and any form of personally identifiable information are never collected. This follows the same telemetry principles used by Stripe CLI and Vercel CLI. Your users' data stays on their machines.
How much overhead does tracking add?
Negligible. Events are sent asynchronously via fire-and-forget HTTP calls that do not block command execution. The SDK adds no measurable latency to your CLI's startup or runtime. If the network request fails due to a firewall, offline environment, or timeout, it is silently dropped with no retry, so your CLI's behavior is never affected.
Can users opt out of tracking?
Yes. Users can set the BETTERMETER_DISABLED=1 environment variable to disable all telemetry. You can also pass disabled: true in the SDK configuration to programmatically disable tracking, for example based on a --no-telemetry flag or a config file preference. When disabled, the SDK is a no-op. No HTTP calls are made.