Getting started
Lua, C# or JavaScript: which language should you learn for FiveM?
FiveM supports Lua, C# and JavaScript. What each runtime is good at, which one frameworks like ESX, QBCore, Qbox and ox use, current versions (Lua 5.4, Node 16/22) and the best choice for a beginner.
Overview
Every FiveM developer asks this on day one, and the honest answer depends less on which language is “best” and more on what you want to build and whose code you want to read. FiveM runs three scripting runtimes side by side — Lua, C# (.NET) and JavaScript — and a single server can use all three at once. This guide compares them on the things that actually matter when you are starting out.
The three runtimes at a glance
| Lua | JavaScript | C# | |
|---|---|---|---|
| Runtime | CfxLua (Lua 5.4 with FiveM extensions) | V8; Node.js on the server | .NET (Mono) |
| Client and server | Both | Both | Both |
| File in the manifest | client.lua | client.js | Client.net.dll |
| Ecosystem | Almost all frameworks and resources | npm packages (server) | NuGet, .NET libraries |
| Typing | Dynamic (types via annotations) | Dynamic, or TypeScript | Static |
| Build step | None | None (or a bundler for TS) | Compile to a DLL |
| Best for | Game logic, frameworks, most jobs | NUI, web APIs, tooling | .NET developers, large codebases |
The manifest decides which runtime loads a file, by extension: .lua goes to Lua, .js to JavaScript and .net.dll to .NET. How the manifest works is covered in what a FiveM resource is.
Lua: the language of the FiveM ecosystem
Lua is small, fast to learn and fast at runtime, and FiveM’s version — CfxLua — adds things game scripting needs: vector types (vector3, vector4), compile-time hashes with backticks (`WEAPON_PISTOL`), and an efficient scheduler for threads and Wait. Since June 2025 every Lua script runs on Lua 5.4; the old lua54 'yes' manifest line still appears in many resources but is no longer needed.
- ESX, QBCore, Qbox and ox_core are Lua, as are ox_lib, ox_inventory, ox_target and nearly every job, shop and HUD you will download.
- Almost every tutorial, forum answer and snippet on the Cfx forum is Lua.
- No build step: edit,
ensurethe resource, test.
RegisterCommand('heal', function()
local ped = PlayerPedId()
SetEntityHealth(ped, GetEntityMaxHealth(ped))
print('healed')
end, false)If you have never programmed, start with Lua basics for FiveM and your first FiveM script.
JavaScript and TypeScript
The JavaScript runtime uses V8 on the client and Node.js on the server. On the server you get Node’s standard library and npm packages — handy for HTTP APIs, Discord bots inside the server process, or talking to external services. The manifest’s node_version directive selects the Node version: 16 is the default and 22 is available.
RegisterCommand('heal', () => {
const ped = PlayerPedId();
SetEntityHealth(ped, GetEntityMaxHealth(ped));
console.log('healed');
}, false);TypeScript works well for larger resources: you write TS, bundle it to one JS file, and reference that file in the manifest. See FiveM scripts in TypeScript. And every in-game interface — inventories, phones, HUDs — is HTML, CSS and JavaScript regardless of your game-logic language, so some JS is unavoidable for UI work.
C#
C# resources are compiled .NET assemblies that reference the CitizenFX.Core.Client or CitizenFX.Core.Server NuGet packages. You get static typing, a real IDE with refactoring, and the .NET library ecosystem. The trade-offs: a compile step, a smaller pool of examples, and fewer people on your team who can read your code if everyone else writes Lua.
using System;
using System.Collections.Generic;
using CitizenFX.Core;
using static CitizenFX.Core.Native.API;
public class Heal : BaseScript
{
public Heal()
{
RegisterCommand("heal", new Action<int, List<object>, string>((source, args, raw) =>
{
var ped = PlayerPedId();
SetEntityHealth(ped, GetEntityMaxHealth(ped));
Debug.WriteLine("healed");
}), false);
}
}Setting up a C# project is covered in C# scripts for FiveM.
Mixing languages on one server
Resources in different languages cooperate through events and exports, which carry plain data (numbers, strings, tables/objects) across runtimes. A Lua framework can call a C# resource’s export, and a JS resource can listen to a Lua event. What you cannot do is share live objects or functions directly between runtimes.
The recommendation
| If you… | Start with |
|---|---|
| are new to programming | Lua |
| want to work with ESX, QBCore, Qbox or ox | Lua |
| want to sell scripts | Lua (buyers expect to read and configure it) |
| build in-game UIs | Lua for logic + HTML/CSS/JS (React or Vue) for the NUI |
| already work in .NET | C# is a reasonable choice |
| already work in TypeScript | TS for tooling-heavy resources, Lua for framework glue |
Frequently asked questions
What programming language does FiveM use?
FiveM supports Lua, C# and JavaScript. Lua is by far the most common, and all major frameworks are written in it.
Is FiveM Lua 5.4?
Yes. Since June 2025 all Lua scripts run on Lua 5.4 and Lua 5.3 is deprecated. The lua54 'yes' manifest line is no longer required.
Which Node.js version does FiveM use?
The server JavaScript runtime defaults to Node.js 16; version 22 can be selected with the node_version manifest directive.
Should I learn Lua or C# for FiveM?
Lua, unless you already know .NET well. Almost all FiveM resources and examples are Lua, so you will read and reuse far more Lua code.
Can I use TypeScript for FiveM?
Yes — write TypeScript and bundle it to JavaScript, then load the bundled file in the manifest. See TypeScript scripts.
Do I need JavaScript for FiveM?
For in-game interfaces, yes: NUI is HTML/CSS/JS. Game logic can stay in Lua.
Need this built, not just explained?
Ten years of FiveM work, from Lua to NUI
Custom resources, React NUI, ESX / QBCore / Qbox integration, OneSync performance audits and security reviews — plus the websites and SEO around your server brand.
Related guides
- Getting startedWhat a FiveM resource is, and how the server loads itA resource is a folder inside resources/ containing an fxmanifest.lua. The manifest declares the format (fx_version 'cerulean', game 'gta5'), which scripts run on the client, the server or both, which extra files clients download, and what the resource depends on. The server starts it when server.cfg says ensure foldername.
- Getting startedClient-side vs server-side in FiveMClient scripts run on each player’s PC and handle what that player sees and does: drawing, input, markers, animations and local effects. Server scripts run once, on your server, and own everything that has value or must be trusted: money, items, jobs, the database and permissions. The client asks; the server decides. Never trust data sent by a client without checking it.
- Getting startedThe Lua you need for FiveM, from zeroAlways declare variables with local. Lua has nil, booleans, numbers, strings, tables and functions; only nil and false are falsy (0 and empty strings are true). Use if/elseif/else, numeric for i = 1, 10, for k, v in pairs(t) and while. Concatenate strings with .. and format with string.format. CfxLua adds vector3, backtick hashes, CreateThread and Wait.
- Getting startedWrite your first FiveM script, step by stepCreate a folder resources/my_first, add an fxmanifest.lua with fx_version 'cerulean', game 'gta5', a client_script and a server_script, then write a client command that loads a model with RequestModel, waits for HasModelLoaded, spawns it with CreateVehicle and seats the player with SetPedIntoVehicle. Add ensure my_first to server.cfg, restart, and type /car adder in game.