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.
How It Works
CFXAdmin resolves the install manifest using a three-tier precedence model:
- User installs a resource via CFXAdmin (ZIP or Marketplace).
- CFXAdmin looks for
cfxainstall.ymlinside the extracted resource root. If found and valid, it is used as the authoritative manifest. - 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.
- If neither exists, the resource is installed with a default copy-and-ensure and an advisory notice is shown to the user.
- Any
install_optiontasks from the resolved manifest are presented in the Install Options modal. - Once the user confirms, all remaining tasks execute in order with conditions evaluated against live server state.
- The result is journaled for rollback.
Schema Reference
Top-Level Fields
| Field | Type | Required | Description |
|---|---|---|---|
schemaVersion | string | required | Must be "1.0". Unknown major versions are rejected. |
id | string | required | Resource slug matching the resource folder name, e.g. qb-multicharacter. |
name | string | required | Human-readable display name shown in the install summary. |
version | string | optional | Semver of the resource version this manifest targets. |
author | string | optional | Manifest author. |
description | string | optional | Short description shown in the install summary. |
integrationCategory | string | optional | Declares which swappable system this resource provides. See Integration Categories below. |
integrationCategories | list | optional | Declares multiple integration categories this resource provides. Use instead of integrationCategory when a single resource covers more than one category. |
metadata | map | optional | Arbitrary key/value pairs for display. Not used by the executor. |
requiresFeatures | list | optional | CFXAdmin feature flags that must be present. Known: sql, lua_patch, comment_line, provider_replace. |
tasks | list | optional | Ordered 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:
- 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: Fuelin its manifest, it will be found and removed. - 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-fuelwill find every config file that has= 'qb-fuel'or= 'LegacyFuel'(or any other known fuel provider) and replace it with= 'my-fuel'automatically.
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:
| Condition | Values | What it checks |
|---|---|---|
framework=qb|qbx|esx | qb, qbx, esx | The server's configured framework. |
inventory=ox|qb | ox, qb | Whether ox_inventory or the default QBCore inventory is active. |
Valid integrationCategory values:
| Value | What it represents | Example resources |
|---|---|---|
Fuel | Vehicle fuel system. | qb-fuel, cdn-fuel, LegacyFuel |
Inventory | Player inventory system. | ox_inventory, qb-inventory |
Target | Target/interaction system (3D context menus). | ox_target, qb-target |
VehicleKeys | Vehicle keys / ownership system. | qb-vehiclekeys, qs-vehiclekeys |
Phone | In-game phone resource. | qb-phone, qs-smartphone-pro |
Banking | Banking UI and account system. | qb-banking, qs-banking, ox_banking |
Multicharacter | Character selection screen. | qb-multicharacter, qs-multicharacter, esx_multicharacter |
Dispatch | Police/emergency dispatch system. | ps-dispatch, cd_dispatch |
Spawn | Player spawn selection screen. | qb-spawn, qs-spawn |
MDT | Mobile data terminal / police records system. | ps-mdt, linden_mdt |
Clothing | Character clothing / appearance system. | qs-appearance, illenium-appearance |
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.
| Field | Type | Required | Description |
|---|---|---|---|
action | string | required | Task action — see Actions. |
condition | string | optional | Condition expression — see Conditions. Omit to always run. |
description | string | optional | Human-readable description for the install summary and journal. |
continueOnError | bool | optional | When true, failure is logged but does not abort the install. Default: false. |
whenMissing | string | optional | Behavior 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.
| Field | Type | Required | Description |
|---|---|---|---|
key | string | required | Stable programmatic key, e.g. remove_qb_spawn. Used in conditions as opt:key=value. |
label | string | recommended | Short label shown next to the control in the modal. |
type | string | optional | boolean (default), choice, or string. |
default | string | optional | Default value: "true"/"false" for boolean; a choice value for choice type. |
choices | list | if type=choice | Available choices. At least one required when type: choice. |
required | bool | optional | When true, a choice option requires selection before proceeding. |
group | string | optional | Visual 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.
| Field | Required | Description |
|---|---|---|
target | required | Resource 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.
| Field | Required | Description |
|---|---|---|
target | required | Resource name that owns the config file. |
file | required | Relative path to the config file, e.g. shared/config.lua. |
luaPath | required | Dot-separated Lua key, e.g. Config.UseExternalCharacters. |
value | required (or valueFromProvider) | New value in Lua syntax. Include quotes for strings: 'my_value'. Omit when using valueFromProvider. |
valueFromProvider | optional | Instead 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.
| Field | Required | Description |
|---|---|---|
target | required | Resource name. |
file | required | Relative file path. |
pattern | required | Literal substring to find. |
replacement | required | Replacement 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.
| Field | Required | Description |
|---|---|---|
target | required | Resource name. |
file | required | Relative file path, e.g. fxmanifest.lua. |
value | required | Substring 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.
| Field | Required | Description |
|---|---|---|
target | required | Resource name (defines the root directory). |
source | required | Source path relative to resource root. |
destination | required | Destination 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.
| Field | Required | Description |
|---|---|---|
target | required | Resource name that owns the file. |
file | required | Relative path to the file. |
anchor | required | Substring identifying the anchor line. |
content | required | Lines to insert. May be multi-line using YAML block scalar (|). |
occurrence | optional | Which match to use: first (default), last, or index:N (0-based). |
ifMissing | optional | error (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.
| Folder | Purpose | Ensured 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 name | Marker comment | Intended 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. |
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.
| Field | Required | Description |
|---|---|---|
ensureTarget | required | Resource or folder to ensure, e.g. ox_lib. |
afterEnsure | required | Existing 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.
| Field | Required | Description |
|---|---|---|
ensureTarget | required | Resource or folder to ensure. |
beforeEnsure | required | Existing ensure target to insert before. |
remove_ensure
Removes all ensure lines that exactly match ensureTarget (case-insensitive). Idempotent — no-op if not present.
| Field | Required | Description |
|---|---|---|
ensureTarget | required | Ensure 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.
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.
| Field | Required | Description |
|---|---|---|
ensureTarget | required | Resource name to ensure within the group, e.g. my-framework-resource. |
group | required | Target group: libs, framework, jobs, or default. See Default Server Structure. |
| Group | Use when… |
|---|---|
libs | Your resource is a shared library that other resources depend on (ox_lib, utility libraries). |
framework | Your resource is a core framework or must start immediately after [libs] — e.g. an alternative framework extension. |
jobs | Your resource is a job script that must start after the framework and core systems are ready. |
default | General-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.
| Field | Required | Description |
|---|---|---|
key | required | Convar key, e.g. UseTarget. |
value | required | New 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.
| Field | Required | Description |
|---|---|---|
migrationId | required | Stable unique identifier for this migration, e.g. my-resource-v1-tables. Once applied, this ID is recorded and the migration is never re-run. |
sqlUp | required | SQL to execute when applying the migration. Use CREATE TABLE IF NOT EXISTS and ALTER TABLE … ADD COLUMN IF NOT EXISTS for idempotent schema changes. |
sqlDown | optional | SQL to execute if the migration is rolled back. If omitted the migration cannot be automatically reverted. |
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.
| Field | Required | Description |
|---|---|---|
message | required | Warning 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.
| Field | Required | Description |
|---|---|---|
message | required | Instruction text shown to the operator. |
docsUrl | optional | Documentation 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.
| Field | Required | Description |
|---|---|---|
message | required | Confirmation prompt shown to the user. |
key | optional | Stable 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).
| Field | Required | Description |
|---|---|---|
message | required | Abort 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.
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.
| Field | Required | Description |
|---|---|---|
name | required | Dependency resource name, e.g. ox_lib. |
url | required | Download URL for the resource ZIP. Must be on the allowed host list. |
installPath | optional | Install path relative to resources root, e.g. [libs]. Auto-detected if omitted (library-style names → [libs]). |
detectBy | optional | How to check for existing install: resource_name (default), folder_name, manifest_name. |
skipIfExists | optional | When true (default), skip download if dependency already exists. |
extractSubfolder | optional | Strip 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.
| Field | Required | Description |
|---|---|---|
message | recommended | The 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"
| Form | Example | Description |
|---|---|---|
framework=val|val2 | framework=qb|qbx | Server framework matches one of the listed values. |
inventory=val|val2 | inventory=ox|qb | Server inventory matches. |
opt:key=val|val2 | opt:remove_qb_spawn=true | User-selected option has the given value. |
Framework Values
| Framework | Condition token |
|---|---|
| QBCore | qb |
| QBox | qbx |
| ESX | esx |
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:
- ZIP extraction — resource files are placed on disk.
- Manifest resolution — CFXAdmin resolves the install manifest using the three-tier precedence order (see Packaged Manifests).
- Validation — manifest is parsed and validated. Invalid manifests fall back to the next precedence level.
- Install Options modal —
install_optiontasks are displayed to the user. - Pre-execution confirmations —
require_confirmationtasks are collected and shown as blocking dialogs. - Provider replacement — conflicting resources for the same integration category are removed (always runs).
- Auto-wire — consumer resources that reference this provider are patched (always runs).
- SQL migrations — database migrations are applied if configured (always runs).
- Manifest tasks — remaining tasks executed in order, conditions evaluated against live server state.
- 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:
- Resource-embedded — a
cfxainstall.ymlfound inside the installed resource. This is how resource developers ship their own install logic. Highest priority. - Packaged — a curated manifest compiled into CFXAdmin for that resource name. Used when the resource doesn't include its own manifest.
- 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.
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 patchingesx_multicharacter— removes conflicting multicharacter resources on ESXox_banking/qb-banking— mutual conflict removalox_inventory/qb-inventory— mutual conflict removalox_target/qb-target— mutual conflict removalox_doorlock/qb-doorlock— mutual conflict removalqb-vehiclekeys/ox-vehiclekeys— mutual conflict removalqb-fuel/cdn-fuel/LegacyFuel— three-way conflict removalqb-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.
cfxainstall.yml in your resource ZIP and CFXAdmin will use it automatically. Your manifest overrides any packaged version without any user action required.