New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

@open-core/framework

Package Overview
Dependencies
Maintainers
2
Versions
25
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@open-core/framework

Secure, event-driven TypeScript Framework & Runtime engine for CitizenFX (Cfx).

latest
Source
npmnpm
Version
1.0.8
Version published
Maintainers
2
Created
Source

CI npm license typescript cli website

OpenCore Framework - Stable v1

OpenCore is a TypeScript multiplayer runtime framework targeting CitizenFX runtimes (Cfx/RageMP) via adapters.

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

Installation

pnpm add @open-core/framework reflect-metadata tsyringe zod uuid

This framework uses TypeScript decorators. Ensure your project has decorators enabled.

Imports and entry points

The package exposes subpath entry points:

  • @open-core/framework (root)
  • @open-core/framework/server
  • @open-core/framework/client

Architecture

OpenCore follows a Ports & Adapters (Hexagonal) architecture.

  • Kernel (src/kernel): engine-agnostic infrastructure (DI, logger, metadata scanning)
  • Runtime (src/runtime): multiplayer execution model (controllers, processors, security, lifecycle)
  • Adapters (src/adapters): platform integration (Cfx, Node testing)

The runtime never auto-detects the platform. Adapters are selected explicitly at bootstrap time.

Cfx game profiles

OpenCore treats CitizenFX (cfx) as the platform and supports game profiles (gta5 and rdr3).

  • Shared runtime APIs (events, exports, transport, DI) are registered through the Cfx adapter.
  • Game-specific behavior is controlled through platform capabilities/config (gameProfile, defaultSpawnModel, etc.).
  • Optional RedM-specific enhancements can be layered as external libraries without changing core runtime contracts.

Operating modes

Each instance runs in exactly one mode configured via Server.init():

  • CORE: authoritative runtime. Typically provides identity/auth/players via exports.
  • RESOURCE: a normal Cfx resource using CORE as provider for some features.
  • STANDALONE: a self-contained runtime (useful for tooling, simulations, or small servers).

Server bootstrap

Initialize the server runtime:

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():

import { Server } from '@open-core/framework/server'

Server.setPrincipalProvider(MyPrincipalProvider)
Server.setSecurityHandler(MySecurityHandler)
Server.setPersistenceProvider(MyPlayerPersistence)
Server.setNetEventSecurityObserver(MyNetEventSecurityObserver)

Controllers and decorators

OpenCore uses a decorator + processor pattern.

Decorators store metadata with Reflect.defineMetadata(). During bootstrap, the MetadataScanner reads metadata and processors register handlers.

Commands

import { Controller, Command, Guard, Throttle, Player } from '@open-core/framework/server'
import { z } from 'zod'

const TransferSchema = z.tuple([z.coerce.number().int().positive(), z.coerce.number().min(1)])

@Controller()
export class BankController {
  @Command({
    command: 'transfer',
    usage: '/transfer <id> <amount>',
    schema: TransferSchema,
  })
  @Guard({ rank: 1 })
  @Throttle(1, 2000)
  async transfer(player: Player, args: z.infer<typeof TransferSchema>) {
    const [targetId, amount] = args
    player.emit('chat:message', `transfer -> ${targetId} (${amount})`)
  }
}

Network events

@OnNet() handlers always receive Player as the first parameter.

import { Controller, OnNet, Player } from '@open-core/framework/server'
import { z } from 'zod'

const PayloadSchema = z.object({ action: z.string(), amount: z.number().int().positive() })

@Controller()
export class ExampleNetController {
  @OnNet('bank:action', { schema: PayloadSchema })
  async onBankAction(player: Player, payload: z.infer<typeof PayloadSchema>) {
    player.emit('chat:message', `action=${payload.action} amount=${payload.amount}`)
  }
}

Security decorators

  • @Guard({ rank }) or @Guard({ permission })
  • @Throttle(limit, windowMs)
  • @RequiresState({ missing: [...] })

Library events

Use library wrappers to emit domain events and @OnLibraryEvent() to observe them.

@OnLibraryEvent() listens to events emitted through library.emit(...) only. It does not listen to emitExternal, emitNetExternal, or emitServer.

import { Server } from '@open-core/framework/server'

const characters = Server.createServerLibrary('characters')

@Controller()
export class CharacterListeners {
  @OnLibraryEvent('characters', 'session:created')
  onSessionCreated(payload: { sessionId: string; playerId: number }) {
    // optional listener for library domain events
  }
}

characters.emit('session:created', { sessionId: 's-1', playerId: 10 })

Client usage follows the same pattern with Client.createClientLibrary(...) and @Client.OnLibraryEvent(...).

Plugins

Plugin contracts are exposed by runtime entrypoint, not by root:

  • Server plugins: @open-core/framework/server
  • Client plugins: @open-core/framework/client
import { Server, type OpenCorePlugin } from '@open-core/framework/server'
import { Client, type OpenCoreClientPlugin } from '@open-core/framework/client'

const serverPlugin: OpenCorePlugin = {
  name: 'server-example',
  install(ctx) {
    ctx.server.registerApiExtension('ExampleServerDecorator', () => {})
  },
}

const clientPlugin: OpenCoreClientPlugin = {
  name: 'client-example',
  install(ctx) {
    ctx.client.registerApiExtension('ExampleClientDecorator', () => {})
  },
}

await Server.init({ mode: 'CORE', plugins: [serverPlugin] })
await Client.init({ mode: 'CORE', plugins: [clientPlugin] })

Module augmentation for plugin APIs:

declare module '@open-core/framework/server' {
  interface ServerPluginApi {
    ExampleServerDecorator: () => void
  }
}

declare module '@open-core/framework/client' {
  interface ClientPluginApi {
    ExampleClientDecorator: () => void
  }
}

Testing

Tests run with Vitest.

pnpm test
pnpm test:unit
pnpm test:integration
pnpm test:coverage

Note: pnpm test does not run benchmarks.

Benchmarks

Benchmarks are split by value, so the default run focuses on framework features that matter for real servers.

pnpm bench
pnpm bench:value
pnpm bench:gold
pnpm bench:startup
pnpm bench:diagnostic
pnpm bench:soak
pnpm bench:load
pnpm bench:all
  • bench / bench:value: value-focused suite. Commands, net events, RPC, lifecycle, ticks, binary path, bootstrap.
  • bench:gold: hot-path load scenarios only.
  • bench:startup: startup and registration cost.
  • bench:diagnostic: internal and low-level synthetic benchmarks.
  • bench:soak: long-running stress scenario.

Snapshot (latest local run)

Use benchmark/reports/ as the source of truth. Results vary by machine and should be compared relatively, not treated as product guarantees.

  • Primary benchmark targets:
    • full command execution
    • full net event handling
    • RPC processing
    • player lifecycle churn
    • tick budget impact
    • bootstrap cost
    • binary transport cost

Full reports and methodology are available in benchmark/README.md.

Reports

Benchmark reports are generated under benchmark/reports/.

  • pnpm bench:all generates aggregated reports (text/json/html)
  • Load metrics used by load benchmarks are persisted in benchmark/reports/.load-metrics.json

For details about the benchmark system, see benchmark/README.md.

Development scripts

pnpm build
pnpm watch
pnpm lint
pnpm lint:fix
pnpm format

License

MPL-2.0. See LICENSE.

Keywords

framework

FAQs

Package last updated on 01 Apr 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts