The Compiler
Overviewβ
The OpenCore Compiler is the technical core of the OpenCore CLI.
It is not just a transpiler or a bundler: it is a monorepo-aware build orchestrator designed specifically for FiveM and similar GTA runtimes.
Its job is to:
- Understand what each environment can and cannot do
- Compile server, client, and UI (NUI) code correctly
- Coordinate multiple resources in parallel
- Produce drop-in ready artifacts for FiveM
All of this is done with performance, safety, and predictability as first-class goals βοΈ
The Compiler as a Monorepo Orchestrator π§ β
An OpenCore project is effectively a monorepo of runtime units:
workspace/
ββ core/
β ββ server/
β ββ client/
β ββ views/
ββ resources/
β ββ inventory/
β β ββ server/
β β ββ client/
β β ββ views/
β ββ jobs/
β ββ chat/
ββ shared/
The compiler:
- Discovers all resources automatically
- Detects entrypoints per environment
- Builds each unit independently
- Runs them in parallel when possible
- Resolves cross-resource framework contracts (CORE β RESOURCE)
Think of it less as βtsc for FiveMβ and more as:
A coordinator that understands the topology of your server
FiveM Runtime Environmentsβ
FiveM runs JavaScript in three fundamentally different environments.
The compiler enforces hard boundaries between them.
Runtime Matrixβ
| Environment | Target | Purpose | What you can use | What will break |
|---|---|---|---|---|
| Server | Node.js | Backend logic | Node APIs, DBs, filesystem | DOM, Web APIs, GTA natives |
| Client | Neutral JS | Gameplay logic | GTA natives, FiveM events | Node APIs, browser APIs |
| Views (NUI) | Browser | UI / HUD | DOM, fetch, UI frameworks | Node APIs, natives |
Server Environment (Node.js)β
The server runs on FiveMβs Node runtime.
- Default: Node 16
- Optional: Node 22 (via
fxmanifest.lua)
Intended responsibilitiesβ
- Authentication & persistence
- Command handling
- Business logic
- External APIs
- Background jobs
Examplesβ
β Allowed
import fs from 'fs'
import crypto from 'crypto'
import pg from 'pg'
β Forbidden
window
document
GetEntityCoords(...)
The compiler:
- Targets Node explicitly
- Keeps
node_modules - Preserves Node globals
Client Environment (Neutral JS / V8)β
Client code runs inside the GTA V client, not Node, not a browser.
This environment is intentionally minimal.
Intended responsibilitiesβ
- Player input
- Game state
- Entity interaction
- Natives and events
Examplesβ
β Allowed
onNet('event', ...)
GetEntityCoords(PlayerPedId())
Math.random()
β Forbidden
fs
process
fetch
window
require('some-lib')
The compiler:
- Bundles everything into a single file
- Strips Node & browser globals
- Fails fast on incompatible imports
This is one of the main reasons a generic bundler is not enough.
Views (NUI / Browser)β
Views run in an embedded Chromium instance.
This is a browser-like environment, but not guaranteed to be modern Chrome.
Intended responsibilitiesβ
- UI / HUD
- Menus
- Web-based interactions
- Styling & animations
Examplesβ
β Allowed
fetch('/api')
window.postMessage(...)
React / Vue / Svelte
β Forbidden
fs
path
process
GTA natives
The compiler:
- Detects the UI framework automatically
- Injects the correct esbuild plugins
- Builds optimized browser bundles
- Copies static assets (HTML, CSS, fonts, images)
Automatic Environment Discovery πβ
The compiler does zero-config discovery.
It scans for:
server.ts,client.ts,index.ts,main.ts- View entrypoints (
views/,ui/,nui/) - Resource boundaries
- Binary files (
bin/,bin/win32,bin/linux)
Diagram:
Resource
ββ server β Node build
ββ client β Neutral JS build
ββ views β Browser build
If an environment does not exist, it is simply skipped.
Technology Stackβ
The compiler is a hybrid system, each tool doing exactly what itβs best at:
- Go β orchestration, parallelism, filesystem, process control
- SWC (Rust) β TypeScript, decorators, metadata reflection
- esbuild β ultra-fast bundling and linking
- Custom plugins β FiveM-specific constraints
This separation is deliberate:
- Go handles scale (Esbuild and CLI)
- Rust handles syntax & speed (SWC)
- JS tooling handles ecosystem compatibility (embedded js)
Parallel Build Model β‘β
Traditional builds are sequential.
OpenCore is not.
ββββββββββββββ
β Resource A ββββ
ββββββββββββββ€ ββ parallel workers β‘
β Resource B ββββ€
ββββββββββββββ€ β
β Resource C ββββ
ββββββββββββββ
Each resource:
- Is built in isolation
- Has its own dependency graph
- Does not block others
Typical results:
- 8β12 resources β < 1 second build
- CPU-bound, not IO-bound
Why this Mattersβ
The compiler guarantees that:
- Server code cannot accidentally leak into client
- Client code cannot rely on Node
- UI code stays browser-safe
- CORE and RESOURCE builds stay contract-correct
- Large projects remain maintainable and fast
In short:
The compiler encodes the rules of the FiveM universe so you donβt have to remember them.
Final Mental Modelβ
CLI
ββ Compiler
ββ Discovers project structure
ββ Orchestrates monorepo builds
ββ Enforces runtime boundaries
ββ Runs parallel workers
ββ Emits ready-to-run resources
This is what enables OpenCore to scale from:
- a single script to
- a full modular server architecture π