Skip to content

Repository files navigation

cfx-api

The fastest way to read the Cfx.re, FiveM and RedM server list from Node.js.

npm version npm downloads license stars tests TypeScript ready


cfx-api lets you query the public Cfx.re infrastructure with a clean, fully typed API: the complete server list (decoded from the binary streamRedir feed), a single server, featured servers, server icons, the Cfx.re status page, and a game server's own endpoints.

Table of contents

Features

  • 🌍 Full server list decoded from the protobuf streamRedir feed, with client-side filters.
  • 🔎 Single server lookup with the complete payload (players, resources, owner, variables…).
  • Featured servers as shown on the official server list.
  • 🖼️ Server icons as a Buffer or a ready-to-use URL.
  • 🛰️ Direct game server queries (info.json, dynamic.json, players.json).
  • 📊 Cfx.re status and unresolved incidents.
  • 🧩 Fully typed, zero configuration, works in JavaScript and TypeScript.

Installation

npm i cfx-api

Quick start

const cfx = require("cfx-api")

;(async () => {
  const servers = await cfx.servers.all({ minPlayers: 1, limit: 50 })
  console.log(`${servers.length} servers fetched`)

  const status = await cfx.status.get()
  console.log(status.everythingOk ? "All systems operational" : "Cfx.re is experiencing issues")
})()
import { servers, status } from "cfx-api"

API

The library exposes two namespaces, servers and status. Standalone fetch* functions are also available as aliases.

servers

servers.all(filters?)

Fetches the full public server list and decodes it. Returns an array of CitizenServer.

const list = await cfx.servers.all({
  locale: "en-US",
  gametype: "Roleplay",
  minPlayers: 10,
  maxPlayers: 1000,
  tag: "drift",
  onlyOpen: true,
  search: "my community",
  limit: 100,
})
Filter Type Description
locale string Keep only servers using this locale
gametype string Keep only servers with this game type
mapname string Keep only servers with this map name
minPlayers number Minimum connected players
maxPlayers number Maximum connected players
tag string Keep only servers exposing this tag
onlyOpen boolean Exclude full servers
search string Case-insensitive match on the hostname
limit number Stop after this many matching servers

servers.single(id)

Fetches a single server by its join id. Returns a CitizenServer.

const server = await cfx.servers.single("xxxxxx")
console.log(server.hostname, server.playersCount, server.maxPlayers)

servers.featured()

Fetches the featured servers shown on the official server list. Returns a CfxFeaturedServers.

const featured = await cfx.servers.featured()
console.log(featured.homePageServer.name)
console.log(featured.allIds)

servers.icon(id, iconVersion) and servers.iconUrl(id, iconVersion)

Fetches the server icon as a Buffer, or builds its URL.

const server = await cfx.servers.single("xxxxxx")
const icon = await cfx.servers.icon(server.id, server.iconVersion)
const url = cfx.servers.iconUrl(server.id, server.iconVersion)

servers.info(address), servers.dynamic(address), servers.players(address)

Queries a game server directly through its own endpoints, using an ip:port address.

const dynamic = await cfx.servers.dynamic("127.0.0.1:30120")
const players = await cfx.servers.players("127.0.0.1:30120")
const info = await cfx.servers.info("127.0.0.1:30120")

status

status.get()

Returns a CfxStatus.

const status = await cfx.status.get()
console.log(status.level, status.description, status.everythingOk)

const components = await status.fetchComponents()
for (const component of components) {
  console.log(`${component.name}: ${component.status}`)
}

status.unresolvedIncidents()

Returns the unresolved incidents.

const incidents = await cfx.status.unresolvedIncidents()
console.log(incidents.incidents.length)

Aliases

cfx.fetchServer(id)
cfx.fetchAllServers(filters)
cfx.fetchFeaturedServers()
cfx.fetchServerIcon(id, iconVersion)
cfx.fetchStatus()
cfx.fetchUnresolvedIncidents()

Recipes

Total players online across the whole network

const all = await cfx.servers.all()
const players = all.reduce((sum, server) => sum + server.playersCount, 0)
console.log(`${all.length} servers, ${players} players online`)

Top 10 servers by player count

const all = await cfx.servers.all({ minPlayers: 1 })
const top = all.sort((a, b) => b.playersCount - a.playersCount).slice(0, 10)
top.forEach((s) => console.log(`${s.playersCount}/${s.maxPlayers} - ${s.hostname}`))

Find roleplay servers in a given language with free slots

const servers = await cfx.servers.all({
  locale: "fr-FR",
  gametype: "Roleplay",
  onlyOpen: true,
})

Check whether a player is connected to a server

const server = await cfx.servers.single("xxxxxx")
console.log(server.isPlayerOnline("PlayerName"))

The CitizenServer model

A decoded server exposes the following members.

Member Description
id Join id
hostname Display name
playersCount / maxPlayers Connected players and slot count
players Connected players
gameType / mapName Game type and map
resources Loaded resources
serverVersion Server build
publicVariables Raw server variables
tags Parsed tags
connectedEndpoints / connectEndpoint Connection endpoints
upvotePower / burstPower Listing power values
iconVersion / iconUrl Server icon
ownerId / ownerName / ownerProfileUrl / ownerAvatarUrl Owner information
locale Server locale
joinUrl cfx.re/join link
isFiveM / isRedM Platform helpers
isFull Whether the server is full
isOneSyncEnabled OneSync state
projectName / projectDesc Project metadata
bannerConnecting / bannerDetail Banner URLs

Helper methods: hasResource(name), hasAnyResourceStartingWith(prefix), hasTag(tag), isPlayerOnline(name).

License

MIT © PABLO-1610

About

Fully typed Node.js/TypeScript library to read the Cfx.re, FiveM and RedM server list, single servers, featured servers, icons, status and direct game server data.

Topics

Resources

Stars

Watchers

Forks

Releases

Used by

Contributors

Languages