Lua Starter Template
The standard FiveM resource structure explained with a complete working template. Start every script with this foundation.
Prerequisites
- โVS Code installed with Lua extension
- โA local or remote FiveM server running
- โBasic understanding of any programming language
1.Resource Folder Structure
Every FiveM resource follows the same structure. The manifest file tells FiveM what to load and how.
my-script/
โโโ fxmanifest.lua # Resource manifest (required)
โโโ client/
โ โโโ main.lua # Client-side code (runs on player's PC)
โโโ server/
โ โโโ main.lua # Server-side code (runs on server)
โโโ shared/
โ โโโ config.lua # Shared configuration
โโโ html/ # NUI files (optional, for UI)
โโโ index.html
โโโ style.css
โโโ script.js2.fxmanifest.lua
The manifest is the first file FiveM reads. It tells the server what files to load, in what order, and what features your resource uses.
fx_version 'cerulean'
game 'gta5'
name 'my-script'
description 'A template FiveM resource'
author 'Your Name'
version '1.0.0'
shared_scripts {
'shared/*.lua',
}
client_scripts {
'client/*.lua',
}
server_scripts {
'server/*.lua',
}
-- Uncomment if using NUI:
-- ui_page 'html/index.html'
-- files { 'html/index.html', 'html/style.css', 'html/script.js' }The lua54 'yes' flag is deprecated as of June 2025 โ all FiveM scripts now run Lua 5.4 by default, so you no longer need to set it.
3.Client Script Template
-- Client-side code runs on each player's machine
-- Use for: rendering UI, handling input, visual effects, animations
local Config = Config or {}
-- Example: Register a command
RegisterCommand('hello', function()
-- Show notification to player
SetNotificationTextEntry('STRING')
AddTextComponentString('Hello from my first script!')
DrawNotification(false, false)
end, false)
-- Example: Listen for a server event
RegisterNetEvent('my-script:client:notify', function(message)
SetNotificationTextEntry('STRING')
AddTextComponentString(message)
DrawNotification(false, false)
end)
print('[my-script] Client loaded successfully')4.Server Script Template
-- Server-side code runs once on the server
-- Use for: database operations, validation, cross-player logic
local Config = Config or {}
-- Example: Server command with player validation
RegisterCommand('announce', function(source, args)
-- source = 0 means console, otherwise it's a player ID
if source > 0 then
-- Check if player has permission
if not IsPlayerAceAllowed(source, 'command.announce') then
TriggerClientEvent('my-script:client:notify', source, 'No permission')
return
end
end
local message = table.concat(args, ' ')
-- Send to ALL players
TriggerClientEvent('my-script:client:notify', -1, message)
print(('[my-script] Announcement: %s'):format(message))
end, false)
print('[my-script] Server loaded successfully')6.Event System
FiveM uses events for client-server communication. Understanding events is the most important concept in FiveM development.
- TriggerEvent(name, ...) โ trigger a local event (same side only)
- TriggerServerEvent(name, ...) โ client sends to server
- TriggerClientEvent(name, playerId, ...) โ server sends to specific client
- TriggerClientEvent(name, -1, ...) โ server sends to ALL clients
- RegisterNetEvent(name, handler) โ listen for network events
Always use RegisterNetEvent for events that cross the network. Never trust client-sent data on the server โ validate everything.
Template Ready
You now have a working FiveM resource template. Copy this structure for every new script you build. Next, follow the First Script Walkthrough to build something useful.