Docs / cfxainstall.yml

cfxainstall.yml

Bundle an install manifest with your resource for zero-friction, configuration-aware installs on any CFXAdmin-managed server.

Overview

A cfxainstall.yml file placed in the root of your FiveM resource directory is automatically detected by CFXAdmin when a user installs your resource. When present and valid, it is the authoritative source for all install-time steps — conflict removal, config patching, option dialogs, and more.

Who is this for? Resource developers who want their scripts to install correctly on any CFXAdmin-managed server — handling framework detection, config patching, and conflicting resource removal automatically.

How It Works

CFXAdmin resolves the install manifest using a three-tier precedence model:

  1. User installs a resource via CFXAdmin (ZIP or Marketplace).
  2. CFXAdmin looks for cfxainstall.yml inside the extracted resource root. If found and valid, it is used as the authoritative manifest.
  3. If no embedded manifest is found (or it fails validation), CFXAdmin checks its packaged manifests — curated YAML files compiled into the app for well-known resources.
  4. If neither exists, the resource is installed with a default copy-and-ensure and an advisory notice is shown to the user.
  5. Any install_option tasks from the resolved manifest are presented in the Install Options modal.
  6. Once the user confirms, all remaining tasks execute in order with conditions evaluated against live server state.
  7. The result is journaled for rollback.

Schema Reference

Top-Level Fields

FieldTypeRequiredDescription
schemaVersionstringrequiredMust be "1.0". Unknown major versions are rejected.
idstringrequiredResource slug matching the resource folder name, e.g. qb-multicharacter.
namestringrequiredHuman-readable display name shown in the install summary.
versionstringoptionalSemver of the resource version this manifest targets.
authorstringoptionalManifest author.
descriptionstringoptionalShort description shown in the install summary.
integrationCategorystringoptionalDeclares which swappable system this resource provides. See Integration Categories below.
integrationCategorieslistoptionalDeclares multiple integration categories this resource provides. Use instead of integrationCategory when a single resource covers more than one category.
metadatamapoptionalArbitrary key/value pairs for display. Not used by the executor.
requiresFeatureslistoptionalCFXAdmin feature flags that must be present. Known: sql, lua_patch, comment_line, provider_replace.
taskslistoptionalOrdered list of tasks to execute during install.

Integration Categories

integrationCategory declares what swappable system this resource provides — fuel, inventory, phone, etc. When a resource with this field is installed, CFXAdmin automatically does two things:

  1. Auto-removes competing providers — CFXAdmin scans all installed resources (by reading their manifests and built-in definitions) for any resource in the same category and prompts the user to remove them. This works for any resource regardless of whether CFXAdmin has built-in knowledge of it — if it has integrationCategory: Fuel in its manifest, it will be found and removed.
  2. Auto-wires other resources — CFXAdmin scans the config files of all other installed resources for any Lua string value that matches a known provider name for that category and updates it to the new resource's name. For example, installing a new fuel resource called my-fuel will find every config file that has = 'qb-fuel' or = 'LegacyFuel' (or any other known fuel provider) and replace it with = 'my-fuel' automatically.
Why this covers resources CFXAdmin has never seen before The auto-remove scans installed resources' actual cfxainstall.yml files at runtime, so it finds any competing provider regardless of how many there are. The auto-wire does the same — it builds the full set of known provider names from both built-in definitions and installed manifests before scanning, so it doesn't need a pre-compiled list of every possible fuel or inventory resource name.

In addition to the automatic behaviour, your manifest can use conditions to configure your own resource's files based on the active provider for another category. For example, patching your config to reference whichever inventory system is installed:

- action: operation
  operationType: patch_lua_value
  target: my-job
  file: config/config.lua
  luaPath: Config.Inventory
  value: "'ox_inventory'"
  condition: "inventory=ox"

- action: operation
  operationType: patch_lua_value
  target: my-job
  file: config/config.lua
  luaPath: Config.Inventory
  value: "'qb-inventory'"
  condition: "inventory=qb"

Supported condition clauses for checking the active provider of your own config:

ConditionValuesWhat it checks
framework=qb|qbx|esxqb, qbx, esxThe server's configured framework.
inventory=ox|qbox, qbWhether ox_inventory or the default QBCore inventory is active.

Valid integrationCategory values:

ValueWhat it representsExample resources
FuelVehicle fuel system.qb-fuel, cdn-fuel, LegacyFuel
InventoryPlayer inventory system.ox_inventory, qb-inventory
TargetTarget/interaction system (3D context menus).ox_target, qb-target
VehicleKeysVehicle keys / ownership system.qb-vehiclekeys, qs-vehiclekeys
PhoneIn-game phone resource.qb-phone, qs-smartphone-pro
BankingBanking UI and account system.qb-banking, qs-banking, ox_banking
MulticharacterCharacter selection screen.qb-multicharacter, qs-multicharacter, esx_multicharacter
DispatchPolice/emergency dispatch system.ps-dispatch, cd_dispatch
SpawnPlayer spawn selection screen.qb-spawn, qs-spawn
MDTMobile data terminal / police records system.ps-mdt, linden_mdt
ClothingCharacter clothing / appearance system.qs-appearance, illenium-appearance
You still control conflict removal in your manifest The auto-remove prompts the user to confirm before removing anything. If you also include explicit remove_resource tasks in your manifest, those run during the install phase and are not affected by the auto-remove. You can rely on auto-remove for unknown competitors and use remove_resource for cases where you need guaranteed removal as part of the install flow.

Task Fields

Every task shares these universal fields. Action-specific fields are described per action below.

FieldTypeRequiredDescription
actionstringrequiredTask action — see Actions.
conditionstringoptionalCondition expression — see Conditions. Omit to always run.
descriptionstringoptionalHuman-readable description for the install summary and journal.
continueOnErrorbooloptionalWhen true, failure is logged but does not abort the install. Default: false.
whenMissingstringoptionalBehavior when target file is not found: skip (default), warn, or error.

Actions

install_option

Declares a user-visible choice shown in the Install Options modal before any files are written. Reference the option key in condition expressions on later tasks.

FieldTypeRequiredDescription
keystringrequiredStable programmatic key, e.g. remove_qb_spawn. Used in conditions as opt:key=value.
labelstringrecommendedShort label shown next to the control in the modal.
typestringoptionalboolean (default), choice, or string.
defaultstringoptionalDefault value: "true"/"false" for boolean; a choice value for choice type.
choiceslistif type=choiceAvailable choices. At least one required when type: choice.
requiredbooloptionalWhen true, a choice option requires selection before proceeding.
groupstringoptionalVisual group header in the modal. Default: "General".
- action: install_option
  key: remove_qb_spawn
  type: boolean
  label: "Replace qb-spawn with built-in spawn selector"
  description: "Removes qb-spawn and uses the resource's built-in spawn selector."
  default: "false"
  group: "Spawn Selector"

operation

Performs a declarative file or resource operation. Select the specific behaviour with operationType. See Operation Types below for all supported types and their required fields.

Operation Types

remove_resource

Removes an installed resource from the server, moving it to a backup location for rollback. Use whenMissing: skip to make removal non-fatal when the resource may not be present.

FieldRequiredDescription
targetrequiredResource name to remove, e.g. qb-multicharacter.
- action: operation
  operationType: remove_resource
  target: qb-multicharacter
  condition: "framework=qb|qbx"
  whenMissing: skip
  description: "Remove qb-multicharacter (replaced by qs-multicharacter)"

patch_lua_value

Patches a single Lua key in a config file using dot-notation path. Handles both prefixed (Config.Key = value) and contained (Key = value) config formats.

FieldRequiredDescription
targetrequiredResource name that owns the config file.
filerequiredRelative path to the config file, e.g. shared/config.lua.
luaPathrequiredDot-separated Lua key, e.g. Config.UseExternalCharacters.
valuerequired (or valueFromProvider)New value in Lua syntax. Include quotes for strings: 'my_value'. Omit when using valueFromProvider.
valueFromProvideroptionalInstead of a literal value, automatically resolves the active provider name for the given integration category. E.g. Fuel sets the value to the currently installed fuel resource name (such as 'qb-fuel'). Useful for writing the correct provider name into another resource's config without knowing which one is installed.
# Explicit value (conditional on which inventory is installed)
- action: operation
  operationType: patch_lua_value
  target: qbx_core
  file: config/client.lua
  luaPath: useExternalCharacters
  value: "true"
  condition: "framework=qbx"

# Auto-resolved value: sets Config.Fuel to the name of whatever fuel resource is installed
- action: operation
  operationType: patch_lua_value
  target: my-job
  file: shared/config.lua
  luaPath: Config.Fuel
  valueFromProvider: Fuel

patch_text_replace

Literal find-and-replace in a file. Replaces the first occurrence of pattern.

FieldRequiredDescription
targetrequiredResource name.
filerequiredRelative file path.
patternrequiredLiteral substring to find.
replacementrequiredReplacement text. May be empty to delete the pattern.

comment_line / uncomment_line

Comments out or uncomments the first line containing value as a substring. Preserves leading whitespace. Idempotent — already-commented lines are skipped.

FieldRequiredDescription
targetrequiredResource name.
filerequiredRelative file path, e.g. fxmanifest.lua.
valuerequiredSubstring identifying the target line.
- action: operation
  operationType: comment_line
  target: qb-multicharacter
  file: fxmanifest.lua
  value: "@qb-apartments/config.lua"
  condition: "framework=esx|qbx"

copy_file / move_file

Copies or moves a file within the resource folder. move_file removes the source after a successful copy.

FieldRequiredDescription
targetrequiredResource name (defines the root directory).
sourcerequiredSource path relative to resource root.
destinationrequiredDestination path relative to resource root.

delete_file

Deletes a file within the resource folder. Use whenMissing: skip to make this non-fatal.

ensure_line / ensure_folder

Advisory — notes that a server.cfg ensure line or folder should exist. Recorded as informational notes in the install summary. CFXAdmin's standard install flow handles server.cfg editing automatically.

Anchor Insert Operations

insert_after_anchor / insert_before_anchor

Inserts one or more lines of content immediately after (or before) the first line containing anchor as a substring. Preserves the anchor line's leading indentation on inserted content. Idempotent — if the content is already present adjacent to the anchor, the operation is skipped.

FieldRequiredDescription
targetrequiredResource name that owns the file.
filerequiredRelative path to the file.
anchorrequiredSubstring identifying the anchor line.
contentrequiredLines to insert. May be multi-line using YAML block scalar (|).
occurrenceoptionalWhich match to use: first (default), last, or index:N (0-based).
ifMissingoptionalerror (default — fail closed) or skip.
- action: operation
  operationType: insert_after_anchor
  target: qbx_core
  file: config/server.lua
  anchor: "Config.UseExternalCharacters"
  content: |
    Config.UseExternalCharacterSelector = true
  ifMissing: skip
  description: "Enable external character selector config"

server.cfg Operations

Default Server Structure

When CFXAdmin sets up a server it creates a set of standard resource folders and adds a matching ensure [folder] line for each in server.cfg. Any resource placed inside one of these folders is automatically started by FXServer — no individual ensure line is needed for it.

FolderPurposeEnsured by default
[libs]Shared libraries loaded first — ox_lib, oxmysql, etc.Yes — ensure [libs]
[scripts]General-purpose scripts. The default install destination for most resources.Yes — ensure [scripts]
[Mlo]MLO / interior map resources.Yes — ensure [Mlo]
[pdems]Ped / EMS resources.Yes — ensure [pdems]
[clothing]Clothing / character customisation packs.Yes — ensure [clothing]
[vehicles]Vehicle add-on packs.Yes — ensure [vehicles]
[Ox]Overture/Ox resources (ox_core, etc.). Created only when Ox resources are detected.Conditional

In addition, CFXAdmin places marker comments in server.cfg to define named load-order group sections. These are separate from the folder ensures — they allow individual resources to be positioned precisely within a startup order:

Group nameMarker commentIntended for
libs# ── [libs] ──Library resources that everything else depends on. Loads first.
framework# ── [framework] ──The core framework resource (qb-core, es_extended, qbx_core). Loads after libs.
jobs# ── [jobs] ──Job scripts that must start after the framework and core systems.
default# ── [default] ──Everything else — general resources with no special ordering requirement.
Folders vs. groups The folder ensures (ensure [libs], ensure [scripts], etc.) start everything in that folder. The load-order group sections (libs, framework, jobs, default) are independent — they place individual ensure lines in a specific position for resources that need precise startup ordering, regardless of which physical folder they live in.

add_ensure_after

Inserts ensure <ensureTarget> immediately after the line that ensures afterEnsure. Idempotent — no-op if the target ensure already exists anywhere in the file. If afterEnsure is not found, appends at the end and logs a warning.

FieldRequiredDescription
ensureTargetrequiredResource or folder to ensure, e.g. ox_lib.
afterEnsurerequiredExisting ensure target to insert after.
- action: operation
  operationType: add_ensure_after
  ensureTarget: "ox_lib"
  afterEnsure: "[libs]"
  description: "Ensure ox_lib loads immediately after [libs]"

add_ensure_before

Inserts ensure <ensureTarget> immediately before the line that ensures beforeEnsure. Idempotent. If beforeEnsure is not found, prepends near the first existing ensure and warns.

FieldRequiredDescription
ensureTargetrequiredResource or folder to ensure.
beforeEnsurerequiredExisting ensure target to insert before.

remove_ensure

Removes all ensure lines that exactly match ensureTarget (case-insensitive). Idempotent — no-op if not present.

FieldRequiredDescription
ensureTargetrequiredEnsure target to remove.

set_load_order_group

Places ensure <ensureTarget> within a named load-order group section in server.cfg. This operation is the ensure — using it means no separate add_ensure_after or ensure_line task is needed for your resource. If the resource already has an ensure line elsewhere in the file, it is moved to the correct section automatically.

No double-ensure needed CFXAdmin's standard install flow adds your resource's ensure line automatically. set_load_order_group repositions that line into the right section. You do not need an additional add_ensure_after or ensure_line task — the group operation covers it.
FieldRequiredDescription
ensureTargetrequiredResource name to ensure within the group, e.g. my-framework-resource.
grouprequiredTarget group: libs, framework, jobs, or default. See Default Server Structure.
GroupUse when…
libsYour resource is a shared library that other resources depend on (ox_lib, utility libraries).
frameworkYour resource is a core framework or must start immediately after [libs] — e.g. an alternative framework extension.
jobsYour resource is a job script that must start after the framework and core systems are ready.
defaultGeneral-purpose resources with no special startup ordering requirement. Use this if unsure.
- action: operation
  operationType: set_load_order_group
  ensureTarget: "my-framework-extension"
  group: framework
  description: "Load in the framework group, after qb-core"

set_convar

Adds or updates a convar in server.cfg. Detects and preserves the existing command style (set, setr, sets); defaults to setr for new values. Idempotent — no-op if the key is already set to the given value.

FieldRequiredDescription
keyrequiredConvar key, e.g. UseTarget.
valuerequiredNew value.
- action: operation
  operationType: set_convar
  key: "UseTarget"
  value: "true"
  condition: "opt:use_target=true"
  description: "Enable target system convar"

run_sql

Applies a SQL migration to the server's database. Migrations are tracked by migrationId so each migration runs at most once — re-running the install will not re-apply a migration that has already been applied. Requires the sql feature flag in requiresFeatures.

FieldRequiredDescription
migrationIdrequiredStable unique identifier for this migration, e.g. my-resource-v1-tables. Once applied, this ID is recorded and the migration is never re-run.
sqlUprequiredSQL to execute when applying the migration. Use CREATE TABLE IF NOT EXISTS and ALTER TABLE … ADD COLUMN IF NOT EXISTS for idempotent schema changes.
sqlDownoptionalSQL to execute if the migration is rolled back. If omitted the migration cannot be automatically reverted.
Idempotent SQL Although the migration tracker prevents double-runs, it is still best practice to write idempotent SQL using IF NOT EXISTS and ADD COLUMN IF NOT EXISTS. This protects against edge cases where the tracking table itself was reset or migrated.
requiresFeatures:
  - sql

tasks:
  - action: operation
    operationType: run_sql
    migrationId: "my-resource-v1-tables"
    description: "Create my_resource tables"
    sqlUp: |
      CREATE TABLE IF NOT EXISTS `my_resource_data` (
        `id` int(11) NOT NULL AUTO_INCREMENT,
        `identifier` varchar(80) NOT NULL,
        `data` longtext DEFAULT NULL,
        `created_at` timestamp NOT NULL DEFAULT current_timestamp(),
        PRIMARY KEY (`id`),
        KEY `identifier` (`identifier`)
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
    sqlDown: |
      DROP TABLE IF EXISTS `my_resource_data`;

Flow Control Actions

show_warning

Records a warning message shown to the user in a combined dialog after installation completes. Execution continues normally.

FieldRequiredDescription
messagerequiredWarning text shown to the user.

show_manual_step

Adds an operator instruction card to the post-install summary. Use this for steps that cannot be automated — database changes, third-party configuration, etc. Multiple steps are shown as sequential dialogs.

FieldRequiredDescription
messagerequiredInstruction text shown to the operator.
docsUrloptionalDocumentation URL shown alongside the instruction.

require_confirmation

Pauses installation and requires the user to confirm before execution proceeds. If the user cancels, the entire install is aborted. Confirmations are collected and shown before any tasks execute.

FieldRequiredDescription
messagerequiredConfirmation prompt shown to the user.
keyoptionalStable key for this confirmation step.
- action: require_confirmation
  message: "This will remove qb-multicharacter. All character data is preserved in the database. Continue?"
  condition: "framework=qb|qbx"

abort_with_message

Immediately stops all remaining task execution and shows a user-facing error. Use this when a condition makes install impossible (e.g., incompatible framework detected).

FieldRequiredDescription
messagerequiredAbort reason shown to the user.
- action: abort_with_message
  message: "ox_inventory is required. Please install ox_inventory first."
  condition: "inventory=qb"

Dependency Installation

get_dependency

Downloads and installs a dependency resource if it is not already present. Downloads are validated against an allowed host list and a 64 MB size cap. The extracted resource must contain fxmanifest.lua or __resource.lua.

Allowed Hosts Only Only github.com, raw.githubusercontent.com, and codeload.github.com are permitted. URLs from any other host are rejected at validation time with error MANIFEST-062.
FieldRequiredDescription
namerequiredDependency resource name, e.g. ox_lib.
urlrequiredDownload URL for the resource ZIP. Must be on the allowed host list.
installPathoptionalInstall path relative to resources root, e.g. [libs]. Auto-detected if omitted (library-style names → [libs]).
detectByoptionalHow to check for existing install: resource_name (default), folder_name, manifest_name.
skipIfExistsoptionalWhen true (default), skip download if dependency already exists.
extractSubfolderoptionalStrip a wrapper folder from the ZIP (e.g. ox_lib-main). Auto-detected if omitted.
- action: get_dependency
  name: ox_lib
  url: "https://github.com/overextended/ox_lib/releases/latest/download/ox_lib.zip"
  installPath: "[libs]"
  skipIfExists: true
  description: "Install ox_lib if not already present"

add_note

Adds an informational message to the install summary. No files are written.

FieldRequiredDescription
messagerecommendedThe note text. Falls back to description if absent.

Conditions

The condition field on any task controls whether that task runs. Tasks with no condition always run.

Grammar

Clauses are joined by ; (AND — all clauses must be true):

condition: "framework=qb;opt:remove_spawn=true"
FormExampleDescription
framework=val|val2framework=qb|qbxServer framework matches one of the listed values.
inventory=val|val2inventory=ox|qbServer inventory matches.
opt:key=val|val2opt:remove_qb_spawn=trueUser-selected option has the given value.

Framework Values

FrameworkCondition token
QBCoreqb
QBoxqbx
ESXesx

Path Safety

All file paths in file, source, and destination must be relative and must not contain .. or be absolute paths. The validator rejects such paths with error code MANIFEST-060.

All file operations are scoped to the resource's own directory. Cross-resource file writes are not supported — use patch_lua_value with a target pointing to another resource for cross-resource config patching.

Install Flow

Understanding the execution order helps when authoring manifests:

  1. ZIP extraction — resource files are placed on disk.
  2. Manifest resolution — CFXAdmin resolves the install manifest using the three-tier precedence order (see Packaged Manifests).
  3. Validation — manifest is parsed and validated. Invalid manifests fall back to the next precedence level.
  4. Install Options modalinstall_option tasks are displayed to the user.
  5. Pre-execution confirmationsrequire_confirmation tasks are collected and shown as blocking dialogs.
  6. Provider replacement — conflicting resources for the same integration category are removed (always runs).
  7. Auto-wire — consumer resources that reference this provider are patched (always runs).
  8. SQL migrations — database migrations are applied if configured (always runs).
  9. Manifest tasks — remaining tasks executed in order, conditions evaluated against live server state.
  10. Post-install — warnings, manual steps, and the install summary are shown.

Packaged Manifests

CFXAdmin ships curated install manifests for popular resources. These packaged manifests are compiled into the application at build time and act as the authoritative install logic for resources that do not bundle their own cfxainstall.yml.

Manifest Precedence

CFXAdmin resolves the install manifest for a resource using this exact priority order:

  1. Resource-embedded — a cfxainstall.yml found inside the installed resource. This is how resource developers ship their own install logic. Highest priority.
  2. Packaged — a curated manifest compiled into CFXAdmin for that resource name. Used when the resource doesn't include its own manifest.
  3. Default install — if no manifest is found at either level, the resource is installed with a basic copy-and-ensure and an advisory notice is shown.
A resource-embedded cfxainstall.yml always overrides the packaged manifest. Resource developers can ship accurate, version-specific install logic without waiting for a CFXAdmin update.

Current Packaged Resources

The following resources have curated packaged manifests in this CFXAdmin release:

  • qb-multicharacter — framework-conditional conflict removal and fxmanifest patching
  • esx_multicharacter — removes conflicting multicharacter resources on ESX
  • ox_banking / qb-banking — mutual conflict removal
  • ox_inventory / qb-inventory — mutual conflict removal
  • ox_target / qb-target — mutual conflict removal
  • ox_doorlock / qb-doorlock — mutual conflict removal
  • qb-vehiclekeys / ox-vehiclekeys — mutual conflict removal
  • qb-fuel / cdn-fuel / LegacyFuel — three-way conflict removal
  • qb-phone / npwd — mutual conflict removal

Packaged manifests are compiled from the PackagedYml/ folder at build time. To add coverage for a new resource, add a <resource-name>.cfxainstall.yml to that folder — it will be picked up on the next build automatically.

Override Behavior

When a resource ships its own cfxainstall.yml, CFXAdmin uses it in preference to any packaged manifest. An informational note is added to the install summary so operators know which manifest was used.

If the resource-embedded manifest fails validation, CFXAdmin automatically falls back to the packaged manifest (if available) and logs a diagnostic warning. The install is never blocked by a malformed manifest.

For resource developers Bundle a cfxainstall.yml in your resource ZIP and CFXAdmin will use it automatically. Your manifest overrides any packaged version without any user action required.