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

fivem-tool-helper-v2

v1.1.11

Published

FiveM Tool Helper - utility library for FiveM server/client development

Readme

⚡ fivem-tool-helper

Live server watchdog dashboard & utility toolkit for FiveM

npm license node types


📦 Install

npm i fivem-tool-helper

Requires Node.js 18+ (uses native fetch)


🚀 Quick Start

Get server info (one-shot)

import { GetServerInfo } from 'fivem-tool-helper';

const info = await GetServerInfo('https://cfx.re/join/NsguR');

console.log(info.hostname);           // "My Awesome RP Server"
console.log(info.clients);            // 42
console.log(info.maxClients);         // 128
console.log(info.players.length);     // 42
console.log(info.resources.length);   // 156
console.log(info.ping.icmp);          // 45  (ms)
console.log(info.ping.tcp);           // 32  (ms)
console.log(info.ping.http);          // 68  (ms)

Launch the live dashboard

import { startDashboard } from 'fivem-tool-helper';

startDashboard('https://cfx.re/join/NsguR', {
  refreshInterval: 5000,   // ms between refreshes (default: 5000)
  showResources: true,     // show resource list (default: true)
  showPlayers: true,       // show player table (default: true)
  maxPlayerRows: 25,       // max players shown (default: 20)
});

Press Ctrl+C to stop — cursor is restored automatically.


🖥️ Dashboard Preview

╔══════════════════════════════════════════════════════════════╗
║  ⚡ SERVER WATCHDOG              Last update: 15:30:45      ║
╠══════════════════════════════════════════════════════════════╣
║  Server: My Awesome RP Server                               ║
║  IP: 185.123.45.67:30120  │  Game: FiveM  │  Map: skater   ║
╠══════════════════════════════════════════════════════════════╣
║  Players [████████████░░░░░░░░░░] 42/128                    ║
║  ICMP: 45ms  │  TCP: 32ms  │  HTTP: 68ms                   ║
╠══════════════════════════════════════════════════════════════╣
║  ▸ Resources (156)                                          ║
║  hardcap │ esx_legacy │ es_extended │ gcphone │ ...         ║
╠══════════════════════════════════════════════════════════════╣
║  ▸ Players Online (42)                                      ║
║    1 │ PlayerOne           │  45ms                          ║
║    2 │ PlayerTwo           │ 185ms                          ║
║    3 │ PlayerThree         │ 350ms                          ║
╠══════════════════════════════════════════════════════════════╣
║  Refresh: 5s  │  Resources: 156  │  Ctrl+C to exit         ║
╚══════════════════════════════════════════════════════════════╝

Color scheme

| Element | Color | Rule | |---------|-------|------| | Player bar | 🟢 → 🟡 → 🔴 | Green when empty → red when full (gradient) | | Ping ≤ 50 ms | 🟢 Green | Low latency | | Ping 50–150 ms | 🟢→🟡 | Smooth gradient | | Ping 150–300 ms | 🟡→🔴 | Yellow to red | | Ping > 300 ms | 🔴 Red | High latency | | No response | ⚫ Dark gray | Server unreachable | | Server title | 🔵→🟣 | Cyan to magenta gradient |


📖 API Reference

GetServerInfo(cfxJoinUrl)

Resolves a cfx.re/join/{code} URL to the real server IP, then fetches /dynamic.json, /info.json, /players.json and measures ICMP / TCP / HTTP ping — all in parallel.

function GetServerInfo(cfxJoinUrl: string): Promise<ServerInfo>

Returns ServerInfo:

interface ServerInfo {
  hostname: string;        // Server display name
  ip: string;              // Resolved IP address
  port: number;            // Server port
  gametype: string;        // Game type (e.g. "FiveM")
  mapname: string;         // Current map
  clients: number;         // Current player count
  maxClients: number;      // Max player slots
  resources: string[];     // List of started resources
  players: PlayerInfo[];   // Player list (id, name, ping)
  vars: Record<string, string>;  // Server convars
  icon?: string;           // Base64 PNG server icon
  ping: PingResult;        // { icmp, tcp, http } in ms
  online: boolean;         // Whether server responded
  lastUpdate: Date;        // Timestamp of this fetch
}

interface PlayerInfo {
  id: number;
  name: string;
  ping: number;
  endpoint?: string;       // IP:port (if public)
  identifiers?: string[];  // Steam/license IDs (if public)
}

interface PingResult {
  icmp: number | null;     // System ping (spawns `ping`)
  tcp: number | null;      // Raw TCP socket connect time
  http: number | null;     // HTTP round-trip to /dynamic.json
}

startDashboard(cfxJoinUrl, options?)

Starts the live watchdog console with auto-refresh.

function startDashboard(cfxJoinUrl: string, options?: DashboardOptions): void

Options:

| Option | Type | Default | Description | |--------|------|---------|-------------| | refreshInterval | number | 5000 | Milliseconds between data refreshes | | showResources | boolean | true | Show the resource list section | | showPlayers | boolean | true | Show the player table section | | maxPlayerRows | number | 20 | Maximum player rows to display |

stopDashboard()

Stops the dashboard loop and restores the terminal cursor.

function stopDashboard(): void

Low-level exports

For advanced usage you can import individual pieces:

import {
  // Server resolution
  resolveServerAddress,    // cfx.re/join URL → { ip, port }
  extractJoinCode,         // URL → join code string

  // Ping utilities
  pingICMP,                // (host) → ms | null
  pingTCP,                 // (host, port) → ms | null
  pingHTTP,                // (url) → ms | null

  // Renderer (build your own UI)
  renderDashboard,         // (ServerInfo, options, termWidth) → string frame

  // General utilities
  formatMoney,             // (1500) → "$1,500.00"
  clamp,                   // (120, 0, 100) → 100
} from 'fivem-tool-helper';

🔧 How it works

cfx.re/join/{code}
      │
      ▼
 FiveM API  ──→  resolve real IP:port
      │
      ▼
 ┌────────────────────────────────┐
 │  Parallel fetch:               │
 │  • /dynamic.json  (status)     │
 │  • /info.json     (resources)  │
 │  • /players.json  (players)    │
 │  • ICMP ping                   │
 │  • TCP ping                    │
 │  • HTTP ping                   │
 └────────────────────────────────┘
      │
      ▼
 Merge into ServerInfo
      │
      ▼
 Render → single stdout.write()  (flicker-free)
      │
      ▼
 Wait refreshInterval → repeat
  • No screen clearing — uses ANSI cursor repositioning (\x1b[H) + per-line clear (\x1b[K) for flicker-free updates
  • 24-bit true color — RGB gradients via \x1b[38;2;R;G;Bm escape sequences
  • Zero dependencies — only Node.js built-ins (net, child_process, native fetch)

📋 Requirements

  • Node.js ≥ 18 (for native fetch and AbortSignal.timeout)
  • Terminal with true color support (Windows Terminal, iTerm2, most modern terminals)
  • Network access to servers-frontend.fivem.net and the target FiveM server

🛠️ Development

git clone <repo-url>
cd fivem-helper
npm install
npm run build          # Compile TypeScript → dist/
npm run dev            # Watch mode (tsx)

📄 License

MIT