Exports between resources
registerExport, resourceExport, optionalExport, callExport, provideExport and isResourceStarted: offering and calling exports from TypeScript.
An export is a function one resource offers and other resources call (exports["ai-core"].GetMoney(...)). These helpers register exports with both name styles, give you typed access to other resources, and let your code survive a resource that is not running.
import { registerExport, resourceExport, optionalExport, callExport, provideExport, isResourceStarted } from "@aicore-fivem/lib/fivem";
// In a client or server file, the same names also come from "@aicore-fivem/lib/client" or "@aicore-fivem/lib/server".Rules for every export: it is synchronous and returns small values. No promise crosses a resource boundary: when a value needs time, the export takes a callback (done). In a hot path (every frame, every second), mirror the data from events instead of calling an export each time.
registerExport
Offers a function to other resources under name, and also under the same name with the first letter's case swapped (GetPrice and getPrice), so scripts written in either style find it. Use it instead of FiveM's exports(name, fn).
Side: Client and server · Waits: no
registerExport(name: string, handler: (...args: any[]) => unknown): voidLua: no twin; use FiveM's own exports('GetPrice', function(...) end).
Parameters
Prop
Type
Returns
void.
Example
import { registerExport } from "@aicore-fivem/lib/server";
import { readText } from "@aicore-fivem/lib/shared";
const prices = new Map<string, number>([["water", 5], ["bread", 3]]);
// Other resources: exports["my-shop"].GetPrice("water") or exports["my-shop"].getPrice("water")
registerExport("GetPrice", (item: unknown) => {
const name = readText(item, 64);
return name === null ? null : (prices.get(name) ?? null);
});A name you register yourself always wins over a twin. Registering getPrice after GetPrice replaces the twin with your own getPrice handler.
resourceExport
Typed access to another resource's exports. The types come from CitizenExports in @aicore-fivem/shared (ai-core, ai-lib, ai-target, ai-vehicles, ai-inventory and the other ai-* scripts with exports), so your editor knows every export, its arguments and its return type.
Side: Client and server · Waits: no
resourceExport<K extends keyof CitizenExports & string>(resource: K): CitizenExports[K]Lua: no twin; use exports['ai-core']:GetMoney(source, 'cash').
Parameters
Prop
Type
Returns
The resource's exports object. Calling a method calls the export.
Example
import { resourceExport } from "@aicore-fivem/lib/server";
// One handle per file, at the top.
const core = resourceExport("ai-core");
export function payBonus(source: number): boolean {
return core.AddMoney(source, "bank", 500, "Bonus");
}The handle does not check that the resource runs. Calling an export of a stopped resource throws. For a resource that may be missing, use optionalExport.
optionalExport
The same typed exports as resourceExport, but null while the resource is not started. Use it for an optional dependency: your script keeps working when the server does not run that resource.
Side: Client and server · Waits: no
optionalExport<K extends keyof CitizenExports & string>(resource: K): CitizenExports[K] | nullLua: no twin; check GetResourceState('ai-vehicles') == 'started' before calling.
Parameters
Prop
Type
Returns
The exports object while the resource is started, null otherwise.
Example
import { optionalExport } from "@aicore-fivem/lib/server";
function plateOfVehicleId(vehicleId: number): string | null {
// Ask again each time: ai-vehicles can start or stop while the server runs.
return optionalExport("ai-vehicles")?.GetVehicle(vehicleId)?.plate ?? null;
}Call optionalExport at the moment you need it, not once at the top of the file: a handle taken while the resource was stopped stays null.
callExport
Calls an export of a resource that has no types in CitizenExports (a third-party script). The result is unknown: check its shape before you use it.
Side: Client and server · Waits: no
callExport(resource: string, name: string, ...args: unknown[]): unknownLua: no twin; use exports[resource][name](nil, ...) or exports[resource]:Name(...).
Parameters
Prop
Type
Returns
unknown: whatever the export returned.
Example
import { callExport, isResourceStarted } from "@aicore-fivem/lib/client";
function otherHudVisible(): boolean {
if (!isResourceStarted("some-hud")) return true;
const visible = callExport("some-hud", "IsVisible");
return typeof visible === "boolean" ? visible : true;
}Throws Error("<resource> has no export <name>") when the resource has no such export (also when it is stopped). Check isResourceStarted first, or wrap the call in try / catch.
provideExport
Answers exports["<resource>"].<name> for a resource name your resource stands in for with provide in its fxmanifest.lua. FiveM's provide makes the name exist (so dependency lines pass) but does not forward its exports; this helper answers one export of that name. ai-banking uses it to answer qb-banking and Renewed-Banking calls.
Side: Client and server · Waits: no
provideExport(resource: string, name: string, fn: (...args: any[]) => unknown): voidLua: no twin.
Parameters
Prop
Type
Returns
void.
Example
provide 'old-banking'import { provideExport, resourceExport } from "@aicore-fivem/lib/server";
import { readText } from "@aicore-fivem/lib/shared";
const core = resourceExport("ai-core");
// Scripts written for old-banking keep working: exports["old-banking"].GetAccountBalance("police")
provideExport("old-banking", "GetAccountBalance", (job: unknown) => {
const name = readText(job, 32);
return name === null ? 0 : (core.GetSharedMoney("job", name, "bank") ?? 0);
});Register it at resource start, not later: a script that calls the export before your handler exists gets an error. Also use registerExport if your own name should answer the same function.
isResourceStarted
Whether a resource runs right now (its state is "started").
Side: Client and server · Waits: no
isResourceStarted(resource: string): booleanLua: no twin; use GetResourceState(resource) == 'started'.
Parameters
Prop
Type
Returns
true while the resource is started. false when it is stopped, starting, stopping, or not installed.
Example
import { isResourceStarted } from "@aicore-fivem/lib/server";
if (!isResourceStarted("ai-inventory")) console.warn("ai-inventory is not running: shop items will not work.");