04. Resources & fxmanifest
Plain English
In FiveM, a resource is a folder with fxmanifest.lua inside it. The manifest tells the server what’s in the folder and how to load it.
When the server boots, it scans the resources/ directory, reads every fxmanifest.lua, and starts the resources listed in server.cfg with ensure <name>. Restart server, all resources reload.
You’ll write a manifest for every resource you make. They all follow the same shape.
Minimum Resource
The smallest possible resource is a folder with one file:
my_resource/
└── fxmanifest.lua
That’s a valid resource. It just doesn’t do anything yet.
Typical Resource Structure
What you’ll actually build:
my_resource/
├── fxmanifest.lua ← required
├── shared/
│ └── config.lua ← runs on both sides (config tables)
├── client/
│ ├── main.lua ← player-side code
│ └── ui.lua ← extra client file
├── server/
│ ├── main.lua ← server-side code
│ └── database.lua ← extra server file
├── web/ ← NUI source (React/HTML/JS)
│ └── build/ ← compiled NUI output
│ ├── index.html
│ └── assets/
└── locales/
└── en.lua ← translation file
Don’t memorize this - adapt it per project. Smaller resources don’t need every folder.
fxmanifest.lua - Line By Line
The basic shape, every line annotated:
-- which version of the manifest API to use. "cerulean" is current standard, always use it.
fx_version 'cerulean'
-- which game this resource is for. for FiveM, it's always 'gta5'. (RedM uses 'rdr3')
game 'gta5'
-- enable Lua 5.4. this gives you backtick-hashes, integer division, and other modern features.
-- ALWAYS turn this on for new resources.
lua54 'yes'
-- metadata (optional but good to fill in)
author 'Your Name' -- whoever wrote this
description 'My cool resource' -- one-line description
version '1.0.0' -- semver, bump when you ship changes
-- which files run on the player's PC
client_script 'client/main.lua'
-- which files run on the server
server_script 'server/main.lua'
-- which files run on BOTH sides (config tables, helper functions)
shared_script 'shared/config.lua'
Multiple Files
Use the plural forms with a list of paths:
-- client_scripts (plural) takes a table of file paths
client_scripts {
'client/main.lua',
'client/ui.lua',
'client/events.lua',
}
server_scripts {
'@oxmysql/lib/MySQL.lua', -- @ prefix = pull a file from another resource
'server/main.lua',
'server/database.lua',
}
shared_scripts {
'@ox_lib/init.lua', -- imports ox_lib's "lib" global into your resource
'shared/config.lua',
'locales/*.lua', -- glob: matches every .lua file in locales/
}
Load order = list order. shared_scripts always load before client_scripts and server_scripts. So put config files in shared near the top.
The @ Prefix
'@otherresource/path/to/file.lua' means “load this file from another resource into your resource’s runtime”. Common cases:
-- pulls in oxmysql's MySQL global. Lets you call MySQL.query, MySQL.update, etc.
'@oxmysql/lib/MySQL.lua'
-- pulls in ox_lib's lib global. Lets you call lib.notify, lib.callback, etc.
'@ox_lib/init.lua'
If you forget these, you’ll see attempt to index a nil value (global 'MySQL') errors.
Dependencies
Tell the server “these resources must already be running before mine starts”:
-- if any of these aren't running, my resource refuses to start
dependencies {
'ox_lib',
'ox_target',
'oxmysql',
'qbx_core',
}
Why bother? Without dependencies, your resource might start before oxmysql is ready, and your DB calls error. With them, the server fails fast with a clear message instead.
For a single dependency, the singular form works:
dependency 'oxmysql'
NUI (HTML UI)
If your resource has an HTML user interface:
-- the entry point HTML file the client will load
ui_page 'web/build/index.html'
-- list every file the browser needs access to
files {
'web/build/index.html',
'web/build/assets/*.js', -- glob: all JS in assets/
'web/build/assets/*.css', -- glob: all CSS in assets/
'web/build/**/*', -- "**" = recursive glob, every file in subdirs too
}
Files NOT listed in files {} are unreachable from the browser. Forget to add a CSS file → 404, no styles. Forget an image → broken image icon.
Full NUI guide: 07-nui/01-nui-basics.md.
Data Files (Vehicles, Weapons, Peds)
For custom GTA assets like vehicles or weapons:
-- list the data files so they ship with the resource
files {
'data/vehicles.meta',
'data/carcols.meta',
'stream/**/*', -- everything in the stream/ folder
}
-- declare what each meta file is, so the game knows how to load it
data_file 'VEHICLE_METADATA_FILE' 'data/vehicles.meta'
data_file 'CARCOLS_FILE' 'data/carcols.meta'
Anything inside a stream/ subfolder gets auto-streamed to clients - they download it when they join. That’s how custom cars and clothing work.
Provides
Tells the server “I am a substitute for resource X”:
-- if another resource depends on "mysql-async", they can use mine instead
provide 'mysql-async'
You’ll rarely write this - it’s mostly for compat shims (Qbox provides qb-core, oxmysql provides mysql-async).
Real Example - A Qbox Core Resource
This is roughly what qbx_core/fxmanifest.lua looks like:
fx_version 'cerulean' -- modern manifest
game 'gta5' -- FiveM only
lua54 'yes' -- enable Lua 5.4
author 'Qbox'
description 'Qbox Core Framework'
version '1.23.0'
shared_scripts {
'@ox_lib/init.lua', -- ox_lib globals available everywhere
'shared/main.lua', -- main shared file (shared/main.lua loads first)
'config/*.lua', -- glob: every config file
}
client_scripts {
'client/main.lua', -- entry point
'client/*.lua', -- everything else in client/
}
server_scripts {
'@oxmysql/lib/MySQL.lua', -- DB wrapper
'server/main.lua', -- entry point
'server/*.lua', -- everything else
}
dependencies {
'ox_lib', -- must have ox_lib
'oxmysql', -- must have oxmysql
}
Starting Resources
In server.cfg, you tell the server which resources to load:
# "ensure" = start the resource. if it's already running, restart it.
ensure ox_lib # libraries first
ensure oxmysql
ensure qbx_core # framework before anything that depends on it
ensure ox_target
ensure ox_inventory
ensure my_resource # YOUR resource last
Load order matters. Dependencies before dependents. If my_resource says dependency 'qbx_core', then qbx_core must be ensured first.
Resource Lifecycle
Resources fire built-in events when they start and stop. Listen for them to do init/cleanup:
-- fires once for every resource that starts. check if it's YOU.
AddEventHandler('onResourceStart', function(resourceName)
if resourceName ~= GetCurrentResourceName() then return end -- ignore other resources
print('my resource started')
-- do init: load DB tables, register targets, spawn shop peds
end)
-- fires once for every resource that stops. check if it's YOU.
AddEventHandler('onResourceStop', function(resourceName)
if resourceName ~= GetCurrentResourceName() then return end
print('my resource stopped')
-- CLEANUP: delete spawned entities, remove blips, release NUI focus
end)
Always cleanup on onResourceStop. Otherwise: ghost peds, stuck NUI focus, players raging because they can’t move.
Folder Naming Conventions
resources/
├── [libs]/ ← brackets in folder names = visual category, not loaded
│ ├── ox_lib/
│ └── ox_target/
├── [scripts]/
│ ├── [jobs]/
│ │ ├── my_police/
│ │ └── my_mechanic/
│ └── my_resource/
└── noload/ ← convention: disabled resources, server doesn't ensure them
└── old_script/
[brackets] = category folders. They’re not loaded as resources themselves - they’re just for grouping. The server scans recursively and finds resources by their fxmanifest.lua.
noload/ is a convention. Whatever folder isn’t ensured in server.cfg is disabled. Calling it noload is a common pattern, but the name is arbitrary.
Best Practices
- Resource names: lowercase + underscores.
my_shop,player_armory. No spaces, no hyphens, no special chars - exports break. - Use
shared_script '@ox_lib/init.lua'to enablelib.*everywhere. - Configs in
shared/orconfig/. Scripts inclient/andserver/. - Always declare
dependencies {}- fail-fast over weird load-order bugs. onResourceStopcleanup - NUI focus, blips, spawned entities, threads.- Don’t name your resource the same as an existing one - load order chaos.
- Don’t put
.luafiles infiles {}- they already load via*_script. Listing them infiles{}makes them downloadable to clients (a security issue).
Test A Resource
In the server console (or in-game F8 console if you have admin):
start my_resource # start a resource
stop my_resource # stop it
restart my_resource # stop then start. use this every time you change Lua.
refresh # rescan resources/ for newly-added folders
In-game chat works too if you have ACE permission:
/start my_resource
/restart my_resource
TL;DR
- A resource = folder with
fxmanifest.lua. - Declare scripts via
client_script,server_script,shared_script. @otherresource/path= pull a file from another resource.ui_page+files{}= NUI assets.dependencies {}= hard requirements.- Always cleanup in
onResourceStop.
Sources
- Resource Manifest Reference - every field documented
- Introduction to Resources - concepts
- Server commands -
ensure,start,restart
Next folder: 02-events/ - start with 01-local-events.md