Secure, Event-Driven, OOP Engine for FiveM. Stop scripting, start engineering.
npm install @open-core/framework
!npm
!license
!typescript


OpenCore is a TypeScript multiplayer runtime framework targeting FiveM via an adapter.
It is not a gamemode or RP framework. It provides:
- A stable execution model (server and client)
- Dependency Injection and metadata-driven wiring
- An event/command system
- Security primitives (validation, access control, rate limiting)
License: MPL-2.0
Discord Community | Docs | OpenCore CLI
``bash`
pnpm add @open-core/framework reflect-metadata tsyringe zod uuid
This framework uses TypeScript decorators. Ensure your project has decorators enabled.
The package exposes subpath entry points:
- @open-core/framework (root)@open-core/framework/server
- @open-core/framework/client
-
Most projects will import the Server/Client namespaces:
`ts`
import { Server } from '@open-core/framework/server'
OpenCore follows a Ports & Adapters (Hexagonal) architecture.
- Kernel (src/kernel): engine-agnostic infrastructure (DI, logger, metadata scanning)src/runtime
- Runtime (): multiplayer execution model (controllers, processors, security, lifecycle)src/adapters
- Adapters (): platform integration (FiveM, Node testing)
The runtime never auto-detects the platform. Adapters are selected explicitly at bootstrap time.
Each instance runs in exactly one mode configured via Server.init():
- CORE: authoritative runtime. Typically provides identity/auth/players via exports.RESOURCE
- : a normal FiveM resource using CORE as provider for some features.STANDALONE
- : a self-contained runtime (useful for tooling, simulations, or small servers).
Initialize the server runtime:
`ts
import { Server } from '@open-core/framework/server'
await Server.init({
mode: 'CORE'
})
`
Some features require providers (depending on your mode and configuration). Configure them before calling init():
`ts
import { Server } from '@open-core/framework/server'
Server.setPrincipalProvider(MyPrincipalProvider)
Server.setSecurityHandler(MySecurityHandler)
Server.setPersistenceProvider(MyPlayerPersistence)
Server.setNetEventSecurityObserver(MyNetEventSecurityObserver)
`
OpenCore uses a decorator + processor pattern.
Decorators store metadata with Reflect.defineMetadata(). During bootstrap, the MetadataScanner reads metadata and processors register handlers.
`ts
import { Server } from '@open-core/framework/server'
import { z } from 'zod'
const TransferSchema = z.tuple([z.coerce.number().int().positive(), z.coerce.number().min(1)])
@Server.Controller()
export class BankController {
@Server.Command({
command: 'transfer',
usage: '/transfer
schema: TransferSchema,
})
@Server.Guard({ rank: 1 })
@Server.Throttle(1, 2000)
async transfer(player: Server.Player, args: z.infer
const [targetId, amount] = args
player.emit('chat:message', transfer -> ${targetId} (${amount}))`
}
}
@OnNet() handlers always receive Player as the first parameter.
`ts
import { Server } from '@open-core/framework/server'
import { z } from 'zod'
const PayloadSchema = z.object({ action: z.string(), amount: z.number().int().positive() })
@Server.Controller()
export class ExampleNetController {
@Server.OnNet('bank:action', { schema: PayloadSchema })
async onBankAction(player: Server.Player, payload: z.infer
player.emit('chat:message', action=${payload.action} amount=${payload.amount})`
}
}
- @Guard({ rank }) or @Guard({ permission })@Throttle(limit, windowMs)
- @RequiresState({ missing: [...] })
-
Tests run with Vitest.
`bash`
pnpm test
pnpm test:unit
pnpm test:integration
pnpm test:coverage
Note: pnpm test does not run benchmarks.
There are two benchmark suites:
- Core benchmarks (Tinybench)
- Load benchmarks (Vitest project benchmark)
`bash`
pnpm bench:core
pnpm bench:load
pnpm bench:all
These values are a small extract from a recent local run (Dec 22, 2025). Results vary by machine.
- Core
- Decorators - Define metadata (Command): ~5.72M ops/sec (mean 0.17μs)~2.01M ops/sec
- EventBus - Multiple event types: (mean 0.50μs)~1.7M ops/sec
- Dependency Injection (simple resolve): ~28.85K ops/sec
- Load
- Net Events - Simple (10 players): (p95 0.25ms)~1.18M ops/sec
- Net Events - Concurrent (500 players): (p95 0.40ms)~14M ops/sec
- Commands (validated, ~500 players):
Full reports and methodology are available in benchmark/README.md.
Benchmark reports are generated under benchmark/reports/.
- pnpm bench:all generates aggregated reports (text/json/html)benchmark/reports/.load-metrics.json
- Load metrics used by load benchmarks are persisted in
For details about the benchmark system, see benchmark/README.md.
`bash`
pnpm build
pnpm watch
pnpm lint
pnpm lint:fix
pnpm format
OpenCore is designed to be extended via separate packages/resources.
- @open-core/identity: identity and permission system
MPL-2.0. See LICENSE`.