Engineering
Writing FiveM resources in C#
Get started with C# for FiveM: the CitizenFX.Templates dotnet templates, client and server projects, BaseScript, EventHandlers, commands, calling natives through CitizenFX.Core.Native.API, async Delay, building to dist and linking into resources, and when C# makes sense.
Overview
C# is FiveM’s third scripting language, next to Lua and JavaScript. It brings static typing, a mature IDE (Visual Studio or Rider) and the .NET ecosystem. It is less common for roleplay scripts, but popular for larger systems and with developers who already know C#.
01Setting up
dotnet new -i CitizenFX.Templates
mkdir MyResource
cd MyResource
dotnet new cfx-resourceYou get a solution with a client and a server project. Run build.cmd to build release DLLs targeting the .NET version FiveM and FXServer expect; the output lands in dist, with an fxmanifest.
mklink /d C:\FXServer\server-data\resources\[local]\MyResource C:\dev\MyResource\distA client script
using System;
using System.Collections.Generic;
using CitizenFX.Core;
using static CitizenFX.Core.Native.API;
public class Main : BaseScript
{
public Main()
{
EventHandlers["onClientResourceStart"] += new Action<string>(OnStart);
}
private void OnStart(string resource)
{
if (GetCurrentResourceName() != resource) return;
RegisterCommand("coords", new Action<int, List<object>, string>((source, args, raw) =>
{
var pos = GetEntityCoords(PlayerPedId(), true);
Debug.WriteLine($"{pos.X:F2}, {pos.Y:F2}, {pos.Z:F2}");
}), false);
}
}Server events
using System;
using CitizenFX.Core;
public class Main : BaseScript
{
public Main()
{
EventHandlers["fishmarket:sell"] += new Action<Player>(OnSell);
}
private void OnSell([FromSource] Player player)
{
Debug.WriteLine($"{player.Name} wants to sell fish");
// validate on the server, then pay
}
}[FromSource] Player gives you the calling player. Waiting is done with await Delay(ms) inside async methods — never block the thread. Validation rules are the same as for any language: secure server events.
When C# makes sense
- You or your team already work in C#/.NET.
- Large systems where static types and refactoring tools pay off.
- Standalone game modes rather than framework-heavy roleplay scripts (most frameworks and examples are Lua).
Comparisons between the three languages: Lua vs C# vs JavaScript.
Frequently asked questions
Can I write FiveM scripts in C#?
Yes. Use the CitizenFX .NET templates to create client and server projects that build to DLLs.
How do I create a FiveM C# project?
dotnet new -i CitizenFX.Templates, then dotnet new cfx-resource in a new folder.
How do I call natives from C#?
Add using static CitizenFX.Core.Native.API; and call them by name, for example PlayerPedId().
Do ESX and QBCore support C#?
They are Lua frameworks; you can call their exports from C#, but most examples and resources are 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 startedLua, C# or JavaScript: which language should you learn for FiveM?Learn Lua first. It is what almost every public FiveM resource and every major framework (ESX, QBCore, Qbox, ox) is written in, so it is the language you will read, copy and debug most. Add JavaScript or TypeScript when you build NUI interfaces or want the npm ecosystem on the server, and consider C# if you already know .NET and want strong typing.
- EngineeringWriting FiveM resources in TypeScriptInstall @citizenfx/client, @citizenfx/server, TypeScript and esbuild. Write src/client and src/server, bundle each into a single file (dist/client.js, dist/server.js), and list those in the fxmanifest. Client JS has the ES2017 standard library but no browser or Node APIs; server JS runs on Node.js 16 by default, or Node 22 with node_version '22' in the manifest. Type other resources’ exports by extending CitizenExports.
- 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.
- EngineeringEvents in FiveM: how resources and players talkHandle events with AddEventHandler(name, fn); add RegisterNetEvent(name) (or use RegisterNetEvent(name, fn)) to allow the event to arrive over the network. TriggerEvent fires locally on the same side, TriggerServerEvent sends from a client to the server, and TriggerClientEvent(name, target, ...) sends from the server to one player (target = player ID) or everyone (-1). On the server, source is the sending player.