Skip to content

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

javascript
import * as native from '@varion/natives';

native.setEntityVisible(varion.Player.local.scriptID, true, false);

Named imports are also rewritten:

javascript
import { playerPedId, getEntityCoords } from '@varion/natives';

const ped = playerPedId();
const pos = getEntityCoords(ped, true);

Generic Invoke

The generated native typings also expose generic helpers:

javascript
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 health

Async helpers return a Promise that resolves to the real value:

javascript
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 typePlaceholder
number0
name starts with is / has / can / doesfalse
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:

javascript
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:

javascript
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.

Varion Multiplayer Platform