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

@lynxhub/hwmonitor

v0.11.0

Published

Lynx Hardware Monitor is a Node.js module that tracks your system's CPU, GPU, memory, motherboard, storage, and network.

Readme

Lynx Hardware Monitor

NPM Version License GitHub Issues Code Style: Prettier Linter: ESLint Built with: TypeScript

Lynx Hardware Monitor is a Node.js module for monitoring system hardware components such as CPU, GPU, Memory, Motherboard, Storage, Network, Battery, Controller and PSU.

Features

  • Selective Component Monitoring: Choose which hardware components (CPU, GPU, Memory, etc.) to monitor.
  • Detailed Hardware Information: Provides structured data including sensor readings (name, value, type, unit, identifier) for various hardware items.
  • Typed API: Includes TypeScript definitions for HardwareReport, SensorInfo, HardwareItemInfo, MonitorError, and ComponentType.
  • One-Time Data Fetch: Retrieve a snapshot of hardware data.
  • Timed Monitoring: Continuously monitor hardware components at specified intervals.
  • Event-Driven: Emits data events with HardwareReport and error events with MonitorError.
  • Cross-Platform Support: Detects OS (Windows, macOS, Linux) and architecture (x64, arm64) to download the appropriate CLI tool.
  • Automatic CLI Management: Downloads and manages the required LynxHardwareCLI from GitHub releases.
  • .NET Runtime Check: Verifies if the required .NET 9 runtime is installed.

Requirements

  • Node.js: As this is a Node.js module.
  • .NET 9 Runtime: The companion CLI tool (LynxHardwareCLI) requires the .NET 9 runtime to be installed. The module will check for this requirement. You can download it from https://dotnet.microsoft.com/download/dotnet/9.0.
  • Administrative Privileges: Some hardware data may not be accessible unless the application using this module is run with administrative privileges (e.g., "Run as administrator" on Windows, or using sudo on Linux/macOS).

Installation

npm i @lynxhub/hwmonitor

Or if you use yarn:

yarn add @lynxhub/hwmonitor

Usage

import HardwareMonitor, {HardwareReport, MonitorError, ComponentType} from '@lynxhub/hwmonitor';
import {join} from 'node:path';
import {homedir} from 'node:os';

const homeDir = homedir();
// Define a directory where the CLI tool will be downloaded and stored.
// Choose the appropriate path for your OS or make it configurable.
// Example for Windows:
// const cliStorageDir = join(homeDir, 'AppData', 'Local', 'YourApp', 'HardwareMonitorCLI');
// Example for macOS:
// const cliStorageDir = join(homeDir, 'Library', 'Application Support', 'YourApp', 'HardwareMonitorCLI');
// Example for Linux:
// const cliStorageDir = join(homeDir, '.local', 'share', 'YourApp', 'HardwareMonitorCLI');

// Defaulting to a generic path, ensure this directory is writable.
const cliStorageDir = join(homeDir, '.your-app-name', 'HardwareMonitorCLI');

const monitor = new HardwareMonitor();

async function main() {
    try {
        // 1. Check requirements and download the CLI tool
        // This needs a directory path where the CLI can be stored.
        console.log(`Initializing Hardware Monitor... CLI will be stored in: ${cliStorageDir}`);
        await monitor.checkRequirements(cliStorageDir);
        console.log('Requirements checked and CLI is ready.');

        // 2. Get data once
        console.log('\nGetting data once for GPU, CPU, and Uptime...');
        // Monitor only GPU and CPU, with a 5-second timeout. 'uptime' is also requested.
        const reportOnce = await monitor.getDataOnce(['gpu', 'cpu', 'uptime'], 5000);
        console.log('Data (once):');
        console.log(JSON.stringify(reportOnce, null, 2));

        // Example: Accessing specific data
        if (reportOnce.CPU && reportOnce.CPU.length > 0) {
            const cpuName = reportOnce.CPU[0].Name;
            console.log(`\nCPU Name: ${cpuName}`); //
            const cpuLoadSensor = reportOnce.CPU[0].Sensors.find(s => s.Name === 'CPU Total' && s.Type === 'Load'); //
            if (cpuLoadSensor && cpuLoadSensor.Value !== null) {
                console.log(`Current CPU Load: ${cpuLoadSensor.Value.toFixed(2)}%`); //
            }
        }
        if (reportOnce.Uptime) {
            console.log(`System Uptime: ${reportOnce.Uptime.formatted}`); //
        }
        if (reportOnce.ElapsedTime) {
            console.log(`Monitor Elapsed Time: ${reportOnce.ElapsedTime.formatted}`); //
        }

        // 3. Start timed monitoring
        console.log('\nStarting timed monitoring for CPU and Memory (updates every 3 seconds)...');

        monitor.on('data', (data: HardwareReport) => { //
            console.log('\n--- Timed Data Received ---');
            console.log(`Timestamp: ${new Date(data.Timestamp).toISOString()}`); //

            if (data.CPU && data.CPU.length > 0 && data.CPU[0].Sensors) { //
                const cpuLoad = data.CPU[0].Sensors.find(s => s.Name === 'CPU Total' && s.Type === 'Load'); //
                if (cpuLoad && cpuLoad.Value !== null) {
                    console.log(`Current CPU Load: ${cpuLoad.Value.toFixed(2)}%`); //
                }
            }
            if (data.Memory && data.Memory.length > 0 && data.Memory[0].Sensors) { //
                const memoryUsedSensor = data.Memory[0].Sensors.find(s => s.Name === 'Memory Used' && s.Type === 'Data'); //
                const memoryAvailableSensor = data.Memory[0].Sensors.find(s => s.Name === 'Memory Available' && s.Type === 'Data'); //
                if (memoryUsedSensor && memoryUsedSensor.Value !== null) {
                    console.log(`Memory Used: ${memoryUsedSensor.Value.toFixed(2)} ${memoryUsedSensor.Unit}`); //
                }
                if (memoryAvailableSensor && memoryAvailableSensor.Value !== null) {
                    console.log(`Memory Available: ${memoryAvailableSensor.Value.toFixed(2)} ${memoryAvailableSensor.Unit}`); //
                }
            }
            if (data.Uptime) { //
                console.log(`System Uptime: ${data.Uptime.formatted}`); //
            }
            if (data.ElapsedTime) { //
                console.log(`Monitor Elapsed Time: ${data.ElapsedTime.formatted}`); //
            }
            // console.log(JSON.stringify(data, null, 2)); // Optionally log full data
            console.log('--- End Timed Data ---');
        });

        monitor.on('error', (error: MonitorError) => { //
            console.error('\n--- Timed Monitoring Error ---');
            console.error(`Error Type: ${error.type}`); //
            console.error(`Message: ${error.message}`); //
            if (error.stderrData) console.error('Stderr:', error.stderrData); //
            if (error.rawError) console.error('Raw Error:', error.rawError); //
            console.error('--- End Error ---');
        });

        // Start monitoring CPU, Memory, and Uptime. Updates every 3 seconds.
        monitor.startTimed(3000, ['cpu', 'memory', 'uptime']); //

        // Stop timed monitoring after a while (e.g., 15 seconds for this example)
        setTimeout(() => {
            console.log('\nStopping timed monitoring...');
            monitor.stopTimed(); //
            console.log('Monitoring stopped. Example finished.');

            // Example of getting data again after stopping
            // Note: checkRequirements is only needed once unless cliStorageDir changes or CLI needs update.
            console.log('\nGetting data once for Storage and Uptime after stopping timed monitor...');
            monitor.getDataOnce(['storage', 'uptime'], 5000) //
                .then(report => {
                    console.log('Data (storage - after stop):');
                    console.log(JSON.stringify(report, null, 2));
                })
                .catch(err => {
                    const monitorError = err as MonitorError;
                    console.error('Error getting storage data after stop:', monitorError.message);
                });

        }, 15000);

    } catch (error) {
        console.error('\n--- An Error Occurred in Main ---');
        // Using 'as MonitorError' for type assertion to access specific properties
        const monitorError = error as MonitorError;
        console.error(`Error Type: ${monitorError.type || 'N/A'}`);
        console.error(`Message: ${monitorError.message}`);
        if (monitorError.stderrData) {
            console.error('Stderr Data:', monitorError.stderrData);
        }
        if (monitorError.rawError) {
            console.error('Raw Error:', monitorError.rawError);
        }
        // Check for the specific .NET runtime error message
        if (monitorError.message && monitorError.message.includes('.NET 9 runtime')) { //
            console.error(
                "Please ensure .NET 9 runtime is installed. " +
                "Download from: [https://dotnet.microsoft.com/download/dotnet/9.0](https://dotnet.microsoft.com/download/dotnet/9.0)" //
            );
        }
        console.error('--- End Error in Main ---');
    }
}

main();

API

HardwareMonitor

An EventEmitter class.

new HardwareMonitor()

Creates a new instance of the hardware monitor.

async checkRequirements(targetDir: string): Promise<void>

Checks if the .NET 9 runtime is installed and downloads the necessary CLI tool to the specified targetDir. This directory is used to store different versions of the LynxHardwareCLI. Throws an error if .NET 9 is not found or if the CLI download fails.

async getDataOnce(components?: ComponentType[], timeoutMs?: number): Promise<HardwareReport>

Retrieves hardware data once.

  • components (optional): Array of ComponentType (e.g., ['cpu', 'gpu']) to monitor. Defaults to all components.
  • timeoutMs (optional): Timeout in milliseconds for the operation. Defaults to 10000ms. Returns a Promise resolving to a HardwareReport. Throws a MonitorError on failure or timeout.

startTimed(intervalMs: number, components?: ComponentType[]): void

Starts timed monitoring of hardware data.

  • intervalMs: Interval in milliseconds for data updates.
  • components (optional): Array of ComponentType to monitor. Defaults to all. Emits data events with HardwareReport objects and error events with MonitorError objects.

stopTimed(): void

Stops the currently active timed monitoring process.

Events

  • data: Emitted during timed monitoring with a HardwareReport object.
    monitor.on('data', (report: HardwareReport) => { /* ... */ });
  • error: Emitted when an error occurs during timed monitoring or if startTimed is called while already active. Payload is a MonitorError object.
    monitor.on('error', (error: MonitorError) => { /* ... */ });

Types

  • ComponentType: 'cpu' | 'gpu' | 'memory' | 'motherboard' | 'storage' | 'network' | 'battery' | 'controller' | 'psu' | 'uptime'
  • SensorInfo: { Name: string; Value: number | null; Type: string; Unit: string; Identifier: string; }
  • HardwareItemInfo: { Name: string; HardwareType: string; Sensors: SensorInfo[]; SubHardware: HardwareItemInfo[]; }
  • HardwareReport: Contains a Timestamp and arrays for CPU, GPU, Memory, Motherboard, Storage, Network, Battery, Controller and PSU, each being HardwareItemInfo[].
  • MonitorError: Error & { type: 'spawn_error' | 'process_error' | 'json_parse_error' | 'timeout_error'; rawError?: any; stderrData?: string; }

CLI Tool (LynxHardwareCLI)

This module relies on an external CLI tool, LynxHardwareCLI. The HardwareMonitor module automatically handles the download and management of this CLI.

  • Repository: KindaBrazy/LynxHardwareCLI
  • Functionality: The downloadAndExtractLatestCli function within cli_downloader.ts fetches the latest release from the GitHub API, identifies the correct asset based on OS and architecture, downloads it, extracts it to a versioned folder within the targetDir provided to checkRequirements, and cleans up older versions.

Scripts (from package.json)

  • npm run build: Compiles TypeScript to JavaScript. (tsc)
  • npm start: Builds the project and then runs dist/index.js (Note: index.js seems to be the main class definition, not a runnable script in itself without the example usage). The example.ts file provides a runnable example.

Development

  • Linting: Uses ESLint with TypeScript support. Configured in eslint.config.js.
  • Formatting: Uses Prettier. Configured in .prettierrc.json.
  • TypeScript Configuration: tsconfig.json specifies ESNext as target and NodeNext for module system, with output to dist directory.

© 2025 KindaBrazy.