Typescript framework: OpenCore

OpenCore

OpenCore is an open-beta framework for FiveM, written entirely in TypeScript, designed to help developers build multiplayer servers with structure, security, and long-term maintainability.

It applies well-known backend engineering principles to the multiplayer scripting space, taking inspiration from frameworks such as Spring Boot, NestJS, and Angular, while remaining pragmatic and .

The goal is not to add unnecessary complexity, but to reduce ambiguity: to make it clear what code runs where, why it exists, and which guarantees it provides.

Discord: OpenCore Framework


The Problem OpenCore Addresses

Many FiveM projects evolve quickly and organically. Over time, common issues appear:

  • tightly coupled gameplay and infrastructure logic
  • deeply nested callbacks and event chains
  • duplicated or inconsistent security checks
  • code that is difficult to test, reason about, or extend

OpenCore approaches multiplayer development as a long-lived software system, not a collection of isolated scripts.


Architectural Overview

OpenCore follows Ports & Adapters (Hexagonal Architecture) and is organized into three explicit layers.

Kernel (Engine-Agnostic)

  • Dependency Injection (TSyringe)
  • Metadata scanning and decorator processing
  • Logging and configuration infrastructure
  • No dependency on FiveM; runs in pure Node.js

This layer is fully testable and independent of the multiplayer engine.


Runtime (Multiplayer Engine)

  • Controller and service model driven by decorators
  • Centralized security pipeline
  • Player session lifecycle management
  • Unified event system (commands, network events, game events)

This layer defines and enforces multiplayer rules.


Adapters (Platform Integration)

  • FiveM adapter (CitizenFX)
  • Node adapter (testing and tooling)
  • Database adapters (e.g. oxmysql)

Platforms can change without affecting core logic.


Security Model

Security is treated as a first-class concern and enforced consistently.

Authentication

@Server.Public() // everything is private by default
@Server.Command('login')
login(player: Player, credentials: AuthData) {}

Handlers require authentication unless explicitly marked as public.


Authorization

@Server.Guard({ rank: 10 })
@Server.Guard({ permission: 'bank.admin' })
@Server.Command('ban')
ban(player: Server.Player, targetId: string) {}
  • Rank-based and permission-based authorization
  • Wildcard permissions supported (e.g. admin.*)
  • Authorization logic provided by user-defined providers

Rate Limiting

@Server.Throttle(5, 2000)
transfer(player: Server.Player, amount: number) {}

Rate limiting is applied per player and per handler using an in-memory sliding window.


Player State Validation

@Server.RequiresState({ missing: ['dead', 'cuffed'] })
openInventory(player:Server. Player) {}

Handlers can express required or forbidden player states declaratively.


Input Validation

const TransferSchema = z.object({
  targetId: z.string(),
  amount: z.number().positive().max(1_000_000)
})

@Server.Command('transfer', TransferSchema)
transfer(player: Player, data: z.infer<typeof TransferSchema>) {}

Zod is used for type-safe runtime validation.


Decorators

Server-Side

  • @Controller() – controller declaration
  • @Bind(scope) – dependency injection registration
  • @Command() – chat commands
  • @OnNet() – network event handlers
  • @OnFiveMEvent() – FiveM native events
  • @Guard() – access control
  • @Throttle() – rate limiting
  • @RequiresState() – state validation
  • @Public() – authentication bypass
  • @Export() – FiveM exports
  • @OnTick() – server tick loop

Client-Side

  • @Controller()
  • @OnNet()
  • @OnGameEvent()
  • @OnLocalEvent()
  • @Tick()
  • @Interval()
  • @KeyMapping()
  • @NuiCallback()
  • @Export()

CORE ↔ RESOURCE Model

OpenCore separates infrastructure concerns from gameplay logic.

CORE Mode

  • Authoritative runtime
  • Player sessions and identity management
  • Centralized command registration
  • Security enforcement
  • Typed exports for resources

RESOURCE Mode

  • Gameplay-focused modules
  • Consumption of CORE exports
  • Local schema validation

STANDALONE Mode

  • Testing and tooling
  • Small or experimental servers
  • No external dependencies

This model ensures that gameplay code does not bypass security or lifecycle rules.


Core Runtime Services

  • PlayerService – session lifecycle and metadata
  • CommandService – authentication, validation, execution pipeline
  • PrincipalService – authorization enforcement
  • RateLimiterService – request limiting
  • Configuration, chat, database, vehicle, and appearance services
  • ParallelComputeService – worker-based tasks

Extensibility Through Contracts

OpenCore does not define how authentication, authorization, or persistence must work.

Instead, developers implement contracts that the runtime consumes:

abstract class PrincipalProviderContract {
  abstract getPrincipal(player: Player): Promise<Principal | null>
}

This keeps the framework flexible while preserving architectural boundaries.


Performance Considerations

The framework is designed for production environments and evaluated with local benchmarks:

  • High-throughput decorator processing
  • Efficient event dispatch
  • Stable latency under concurrent load
  • Core
    • Decorators - Define metadata (Command): ~5.72M ops/sec (mean 0.17μs)
    • EventBus - Multiple event types: ~2.01M ops/sec (mean 0.50μs)
    • Dependency Injection (simple resolve): ~1.7M ops/sec
  • Load
    • Net Events - Simple (10 players): ~28.85K ops/sec (p95 0.25ms)
    • Net Events - Concurrent (500 players): ~1.18M ops/sec (p95 0.40ms)
    • Commands (validated, ~500 players): ~14M ops/sec

Abstractions are measured and kept within predictable limits.


OpenCore CLI

The OpenCore CLI is the official companion tool, written in Go for maximum performance. It builds complete OpenCore projects—core, resources, and standalone—in a single command, using true parallelism to drastically reduce build times.

Key points:

  • parallel build of multiple resources
  • full project build with one command
  • single binary, no external runtime dependencies
  • extremely fast thanks to Go
  • simple, well-documented configuration

Project Status and Ecosystem

OpenCore is currently in open beta. The architecture is stable, but iteration and feedback are expected.

License: MPL-2.0

OpenCore aims to provide a structured foundation for FiveM projects that need clarity, safety, and room to grow.

Code is accessible Yes
Subscription-based No
Lines (approximately) ~23085 (no tests or benchmarks)
Requirements & dependencies FiveM FXServer, Node.js 18+, TypeScript
Support Yes (GitHub issues)
16 Likes

I saw it No dependency on FiveM; runs in pure Node.js

Is it possible to use the Electron and Vue frameworks to make your own launcher to join a server using FiveM without starting the FiveM platform?