Skip to content

Common concepts ​

The np_* resources share a set of patterns. Each resource's Bridges page has the details for that resource.

Bridges and auto-detection ​

Resources never call a framework or voice resource directly. They go through a bridge: a small Lua table with a fixed contract (for example Phone.Framework.getMoney(src, 'bank') or Hud.Voice.get()), plus one implementation file per supported resource.

bridge/framework/client/1_qbx.lua
bridge/framework/client/2_qb.lua
bridge/framework/client/3_esx.lua
bridge/voice/…
  • Every bridge file starts with Bridge.shouldLoad(kind, name, resource) and returns early unless its resource is started and selected.
  • Config.Framework / Config.Voice select a bridge. 'auto' takes the first one that is started. The files are numbered so that auto prefers qbx over qb (qbx also provides qb-core) and pma-voice over the other voice resources.
  • Optional exports are called through pcall, so a missing or broken dependency degrades a feature instead of throwing errors.
  • Detection runs once at resource start, so start optional dependencies first in server.cfg.
  • np_mdt is the exception to the naming above: it also bridges target, UI and database, prefers ESX, and is overridden with Config.Bridge. See MDT bridges.
KindSupportedFallback
Frameworkqbx_core, qb-core, es_extendednp_hud: standalone · np_phone: required · np_menu: standalone · np_helicam: standalone (ACE roles) · np_mdt: standalone
Voicepma-voice, saltychat, yaca-voicenone: talking indicator only / UI-only calls
Inventoryox_inventory, then the framework inventory–

Configuration ​

  • shared/config.lua holds the core settings. Bigger resources split areas into shared/config/<area>.lua (for example Config.Comms, Config.City).
  • Config files are shared (loaded on client and server), so anything in them is visible to players.

Secrets ​

Tokens, webhooks and peppers never go in a config file. Read them from server convars in server.cfg, using set and not setr, so they aren't replicated to clients:

cfg
set np_phone:fivemanage_token "your-api-key"

NUI ​

  • Each resource has a web/ folder (Vite + React + TypeScript strict) that builds to web/dist.
  • Lua → NUI: SendNUIMessage. NUI → Lua: fetch('https://<resource>/<name>') NUI callbacks.
  • Every resource documents its message contract (see np_hud NUI contract, np_phone architecture and np_menu NUI contract).
  • npm run dev runs the NUI in a browser with mock data, so you can work on the UI without a FiveM server.

Performance ​

  • Nothing polls while it isn't needed. Loops start when there is something to do (in a vehicle, while armed, while the phone is open).
  • The idle resmon target is 0.00 ms.

Security ​

  • The server is authoritative. Money, items, vehicles and ownership are validated on the server, and client values are never trusted.
  • NUI → server calls are rate-limited and type-checked.
  • Server-local events (AddEventHandler) fire only after validation. Never listen to the raw net events from other resources.

np_* FiveM resources