FiveM Lua Scripting: Getting Started with Custom Scripts in 2026
Every custom job, unique mechanic, and special feature on a FiveM server is a "resource" written in Lua. If you can write Lua, you can build anything. Here is how to start.
The Resource Structure
Every FiveM resource is a folder containing:
my_resource/
fxmanifest.lua # Tells FiveM what files are in this resource
client.lua # Code running on each player's client
server.lua # Code running on your server
shared.lua # Code running on both sides
fxmanifest.lua (required):
fx_version 'cerulean'
game 'gta5'
author 'YourName'
description 'My Custom Resource'
version '1.0.0'
shared_script 'shared.lua'
client_script 'client.lua'
server_script 'server.lua'
Client/Server Architecture
Understanding which code runs where is fundamental:
Client-side (client.lua): Access to GTA V native functions (player position, drawing UI, vehicle control). Runs on each connected player's PC.
Server-side (server.lua): Access to server state, database, player management. Runs once on your server machine.
Communication: Client and server communicate through events:
-- Client sends event to server:
TriggerServerEvent('myResource:doSomething', someData)
-- Server handles it:
RegisterNetEvent('myResource:doSomething')
AddEventHandler('myResource:doSomething', function(someData)
local src = source -- The player who fired the event
print('Player ' .. src .. ' sent: ' .. someData)
-- Do server-side logic here
end)
-- Server sends event back to client:
TriggerClientEvent('myResource:response', src, 'done')
Your First Job System (Minimal Example)
-- server.lua
local jobPlayers = {}
RegisterNetEvent('myjob:clockIn')
AddEventHandler('myjob:clockIn', function()
local src = source
jobPlayers[src] = GetGameTimer()
TriggerClientEvent('myjob:started', src)
print('Player ' .. src .. ' clocked in')
end)
RegisterNetEvent('myjob:clockOut')
AddEventHandler('myjob:clockOut', function()
local src = source
if jobPlayers[src] then
local timeWorked = (GetGameTimer() - jobPlayers[src]) / 1000 / 60 -- minutes
local pay = math.floor(timeWorked * 15) -- €15 per minute
-- Add pay logic here (QBCore money function etc.)
jobPlayers[src] = nil
TriggerClientEvent('myjob:ended', src, pay)
end
end)
Learning Resources
- FiveM Docs — Complete native reference
- GTA V native database — Every GTA V function callable from FiveM
- FiveM community Discord — #development channel
Start by reading and modifying existing open-source resources before writing from scratch. The community's qb-smallresources repository contains dozens of small examples perfect for learning.