Client GTA Natives
Client JavaScript can import GTA native declarations from @varion/natives. The client runtime rewrites those imports to the injected native bridge. That bridge is exposed internally to scripts as globalThis.__varionNative.
Import Forms
import * as native from '@varion/natives';
native.setEntityVisible(varion.Player.local.scriptID, true, false);Named imports are also rewritten:
import { playerPedId, getEntityCoords } from '@varion/natives';
const ped = playerPedId();
const pos = getEntityCoords(ped, true);Generic Invoke
The generated native typings also expose generic helpers:
import { invoke, invokeFloat, invokeString, invokeVector3 } from '@varion/natives';
// WARNING: a synchronous invoke does NOT return the real game value. It posts the
// call to the bridge and immediately returns a placeholder (0 here).
const health = invoke('GET_ENTITY_HEALTH', varion.Player.local.scriptID); // => 0, not the healthAsync helpers return a Promise that resolves to the real value:
const coords = await native.invokeAsync('GET_ENTITY_COORDS', varion.Player.local.scriptID, true);Return Values: Sync vs Async
A synchronous native call — invoke('X', ...), invokeFloat / invokeString / invokeVector3, or native.someNative(...) — does NOT return the real game value. It posts the call to the injected bridge and immediately returns a placeholder:
| Result type | Placeholder |
|---|---|
| number | 0 |
name starts with is / has / can / does | false |
| string | "" |
| vector3 | { x: 0, y: 0, z: 0 } |
So const health = invoke('GET_ENTITY_HEALTH', ...) returns 0, not the health. To read the real value use the async helpers, which return a Promise:
const health = await native.invokeFloatAsync('GET_ENTITY_HEALTH', ped);
const coords = await native.invokeVector3Async('GET_ENTITY_COORDS', ped, true);
const name = await native.invokeStringAsync('GET_PLAYER_NAME', playerId);
const value = await native.invokeAsync('SOME_NATIVE', arg1, arg2);The async helpers are invokeAsync, invokeFloatAsync, invokeStringAsync, and invokeVector3Async.
The only exception: sync reads on remote entities
For REMOTE streamed entities the client snapshot is authoritative, so eight natives resolve to the real value synchronously when the first argument is the scriptID of a remote streamed entity:
GET_ENTITY_COORDS, GET_ENTITY_MODEL, GET_ENTITY_SPEED, IS_ENTITY_DEAD, IS_PED_DEAD_OR_DYING, DOES_ENTITY_EXIST, IS_ENTITY_VISIBLE, GET_ENTITY_ALPHA.
This does not apply to the local player, world state, or hash-invoked natives — those still need an async helper.
Game-thread reads via gameBridge
Some game-thread reads (worldToScreen, stat reads, entity queries) go through a separate Promise path called gameBridge, not through native invoke:
const screen = await varion.worldToScreenAsync(x, y, z);
const world = await varion.screenToWorldAsync(screenX, screenY);
const dead = await entity.isDeadAsync();
const speed = await entity.getSpeedAsync();
const exists = await entity.existsAsync();Native Coverage
Of 6673 registered natives, 6379 are callable ("supported"); 294 are blocked by an unsupported signature (Vector3-by-value input, struct / unknown arguments). In addition, under GTA build 3788 about 191 "supported" natives have no live-hash mapping and return "unresolved" at runtime.
Native Catalog
The public native reference is generated from the current client SDK typings:
Source Backing
This page is derived from client/src/scripting/CClientScriptRuntime.cpp, client/src/scripting/CNativeInvoker.cpp, client/src/scripting/CNativeRegistry.generated.cpp and sdk/Varion.Client/types/@varion/natives/index.d.ts.