START HERE·MAKING THINGS HAPPEN·Verified June 2026 · Lua 5.4 · ox_lib 3.x
Learning with an AI assistant?
Copies this whole lesson - every step, code block, and the exact console errors - plus 2026 ground rules (no lua54 'yes', Cfx.re Portal, correct callback signatures) as a ready-to-paste mentor prompt.
Start Here · Making things happen

Exports: share code between resources

An export lets one resource call a function that lives in another resource. That is the whole idea. Instead of copying the same code into every script that needs it, you write the function once in one resource, hand it out, and let other resources call it by name. This is exactly how the big tools you will use later, like ox_lib, frameworks, and inventories, let your script borrow their features.

You'll learn
What an export is, why exports exist, the two halves (register one and call one), and how to share a function between two resources.
Time
~10 minutes
Difficulty
Beginner
You need
A local test server you can restart, and a text editor. If you have not set that up yet, do the test server lesson first, then come back here.
BEFORE YOU START

What an export is

You already know what a function is: a named block of code you run by calling its name. An export takes that one step further. It is a function one resource offers to every other resource on the server, so they can run it too.

A function normally lives inside one file and only that file can call it. An export punches a small, deliberate hole through that wall. The resource that owns the function says "here, anyone may call this one", and other resources call it across the gap.

There are two moves, and only two. First you register the export in the resource that owns the function:

lua
exports('getMoney', getMoney)

Then, from a different resource, you call it by naming the resource and the export:

lua
exports.qu_bank:getMoney(playerId)

The first line publishes a function under the name getMoney. The second line, written in a totally separate resource, runs that function and gets the answer back. We will build both halves in a minute. For now, just hold the shape in your head: one resource offers, another calls.

Vocabulary

export
A function one resource offers to other resources, so they can call it across the resource boundary.
resource
A single folder of code that the server loads and runs as one unit. A server runs many resources side by side.
provider
The resource that owns the function and registers the export. It hands the function out.
consumer
The resource that calls another resource's export. It borrows the function instead of writing its own.

Why exports exist

Picture a server with a bank resource, a job resource, and a shop resource. All three need to know how much money a player has. Without exports, each one would write its own copy of the "read this player's balance" code. Three copies of the same logic. The day you change how money is stored, you have to find and fix all three, and the day you forget one, you get a bug that only shows up in the shop.

Exports kill that duplication. The bank resource owns the money. It registers one export, getMoney. The job resource and the shop resource just call exports.qu_bank:getMoney(...) whenever they need a balance. One source of truth, one place to fix, and everyone else simply asks.

This is also how every framework and library you will ever use works. When you write exports.ox_inventory:GetItemCount(...), you are not running your own code. You are calling a function that lives inside the ox_inventory resource, written by someone else, offered to you as an export. Learning to register and call exports is learning the language that every serious FiveM resource speaks to every other.

The two halves

Every export is two pieces of code in two different places: the resource that provides the function, and the resource that calls it. Get both halves clear and exports stop being mysterious.

Providing: register the function

In the resource that owns the function, you call exports as a function. You hand it two things: the public name other resources will type, and the actual Lua function to run.

lua
local function getMoney(playerId)
    -- look up and return this player's balance
    return 500
end
 
exports('getMoney', function(playerId)
    return getMoney(playerId)
end)

Read exports('getMoney', ...) as "publish a function under the name getMoney". The first argument is the public name, a string. The second argument is the function to run when someone calls that name. The public name and your own function name do not have to match, which lets you keep your real function local and private while still offering one clean name to the outside world.

Calling: name the resource, then the export

In a different resource, you reach the export by naming the resource folder, then the export, joined with a colon.

lua
local balance = exports.qu_bank:getMoney(playerId)

Read it left to right. exports.qu_bank picks the resource you want, by its folder name. The colon then calls its published getMoney function and passes playerId. The answer comes straight back into balance, exactly like calling any normal function. Do not drop the colon. exports.qu_bank:getMoney(playerId) is the form FiveM expects.

Build it

You will make two tiny resources. qu_bank provides an export, and qu_bank_user calls it. When you restart both and run a command, the called value prints in your server console.

Make the two resource folders

The server has one folder per resource.

Inside your server's resources folder, create both of these folders:

text
resources/qu_bank
resources/qu_bank_user

Write qu_bank (the provider)

qu_bank offers a function as an export.

Create qu_bank/fxmanifest.lua with this:

lua
fx_version 'cerulean'
game 'gta5'
 
server_script 'server.lua'

Then create qu_bank/server.lua with this:

lua
local function getMoney(playerId)
return 500
end
 
exports('getMoney', function(playerId)
return getMoney(playerId)
end)

Write qu_bank_user (the consumer)

qu_bank_user calls the provider's export and prints the result.

Create qu_bank_user/fxmanifest.lua with this:

lua
fx_version 'cerulean'
game 'gta5'
 
dependencies {
'qu_bank'
}
 
server_script 'server.lua'

Then create qu_bank_user/server.lua with this:

lua
RegisterCommand('checkbank', function(source)
local balance = exports.qu_bank:getMoney(source)
print('[qu_bank_user] balance is ' .. balance)
end, true)

The dependencies block tells FiveM to start qu_bank first, every time, so the export exists before anyone calls it.

Start both, then test

The cross-resource call prints the expected line.

Open server.cfg and add both lines, provider first:

text
ensure qu_bank
ensure qu_bank_user

Save. In the txAdmin Live Console (the box where you type server commands), start both resources, provider first:

text
ensure qu_bank
ensure qu_bank_user

Now run the command itself in that same console:

text
checkbank

The 500 came back across the resource boundary from qu_bank. You just called a function that lives in one resource from a completely separate one.

Common beginner mistakes

SymptomFix
No such export getMoney in resource qu_bankThree things to check. First, is qu_bank actually started and green in txAdmin? An export from a stopped resource does not exist. Second, is the name spelled and capitalised exactly the same in both the exports('getMoney', ...) line and the exports.qu_bank:getMoney() call? Lua is case sensitive. Third, are both sides server code? Calling a server export from a client script gives this same error, because the export was never registered on the client side.
attempt to index a nil value (field 'qu_bank')qu_bank is not running, or the resource name is misspelled in the call. Confirm ensure qu_bank is in server.cfg and the resource is started before qu_bank_user calls it. The dependencies block in the consumer manifest is what guarantees that order.
The export call errors only sometimes, right after a restartYou called the export before the provider had finished loading. Add the dependencies { 'qu_bank' } block to the consumer manifest so FiveM always starts the provider first, instead of leaving the load order to luck.
You get 'No such export'. Name two things to check first.

Two of the most common causes. One, the provider resource is not running. If qu_bank is stopped or crashed, its exports do not exist, so check that it is started and green in txAdmin. Two, the export name is misspelled or differs in capitalisation between where you registered it, exports('getMoney', ...), and where you call it, exports.qu_bank:getMoney(). Lua is case sensitive, so getMoney and GetMoney are two different names. A third worth remembering: you may be calling a server export from a client script, which never sees it.

Try it yourself

What you can do now

  • Explain that an export is a function one resource offers to other resources.
  • Say why exports exist: so resources reuse each other's code instead of copying it.
  • Register an export with exports('name', fn) in the resource that owns the function.
  • Call another resource's export with exports.resourceName:name(args) and use the value it returns.
  • Remember that server exports and client exports stay on their own side and do not cross over.

You can now wire two resources together, which is most of what real FiveM development is: small pieces calling each other's exports. The next thing every resource needs is a tidy place to keep settings you can change without touching the logic, like a starting balance or a list of allowed jobs. That is what a config file is for. Next up: "config.lua: settings you can safely change".