How config as code works
Three places a definition can live
Each object in your model can be defined in any of three places:
| Source | What it is |
|---|---|
| JSON file | One file per object, in a vx-config folder in your theme or plugin, or in VX's folder in uploads (wp-content/uploads/vx-framework/vx-config) |
| PHP registration | Code in your theme or plugin that defines the object |
| Database | What the dashboard saves |
When the same object (the same key) is defined in more than one place, VX uses this order:
text
database > PHP registration > JSON fileA database copy wins over code. That's what lets you change a code-defined object in the dashboard. PHP wins over JSON, so a JSON file for a key that PHP also defines is ignored.
Where an object comes from
The Source tab on every editor shows where the object currently comes from. There are three possibilities:
- Only the database. A normal dashboard object, with no file behind it. Save to project creates a file for it.
- Only code. Defined in a file, with no database copy. The file is in charge.
- Code, with a database copy on top. The database copy is what the site uses, until you sync it to the file or discard it.
On the Source tab, the copy icon next to the file's description shows the file's path, and copies it when you click it. Its actions work on the saved configuration, so when the editor has changes you haven't saved, VX asks you to save them before it goes on.
Editing modes
For objects that come from code, the Source tab's Settings chooses how the dashboard behaves:
| Mode | What happens when you edit in the dashboard |
|---|---|
| Read only | Nothing: editing is disabled and the file is in charge. This is the default for code-defined objects. |
| Default | Your edits are saved as a database copy on top of the file. Review the differences and sync them to the file when you're ready. |
| Direct | Your edits are written straight into the JSON file. Ideal on a local site, where you then commit the file. Only available for JSON files in VX's folder in uploads. |
With VX Framework Pro, Direct also works for files in your theme's vx-config folder and every folder you register. There it needs permission to edit theme files (in a theme) or plugin files (anywhere else).
The mode is stored per site, so the same file can be in Direct mode on your laptop and Read only on production.
VX writes or removes a JSON file only when you ask it to: Direct mode, writing an object to your project, or removing it from the project. In a folder VX reads but doesn't write to, the Source tab gives you the file's path and its JSON instead, and you save or delete the file yourself. From the dashboard, writing or removing a file needs the same permission as editing the configuration itself. WP-CLI commands are not affected. With VX Framework Pro, writing to a theme's vx-config folder or a folder you register needs permission to edit theme or plugin files, so it is unavailable to users who can't and on sites that set DISALLOW_FILE_EDIT or DISALLOW_FILE_MODS. Configuration stored in the database stays editable either way.
Structure, not content
Configuration describes the shape of your content, never the content itself. Exported files never contain post, term or user values, or environment-specific secrets such as API keys. Icons are exported as inline SVG, so files don't depend on media library IDs that differ between sites.
The one exception is dictionaries: a code-defined dictionary carries its entries in the file, because the entries are its definition.
When two people edit the same object
An object is saved as one document, so two people editing the same object don't merge. If someone saves while you have the editor open, your save is refused, and you reload to continue from their version.
Technical details for LLMs
- States:
db_native,synced(code only; read-only),overridden(code + database; database wins;vx-framework/reset-configdiscards the copy),not_found. - Source modes (
vxframework_source_modes, per environment):locked(default, stored as absence) = Read only;file= Direct (JSON with a writable file only); Default is theoverriddenstate, not a stored mode. Set withvx-framework/set-config-source(database|file|locked); askvx-framework/get-config-sourcefirst. - Resolvable groups:
post_types,taxonomies,fieldsets. Option pages and dictionaries resolve the same way, asoption_pagesanddictionaries. - Icons:
icon(attachment id, environment-bound) andicon_svg(portable, sanitized: allowlisted elements only, no<style>/style, max 256 KB). Export inlines the attachment intoicon_svgand dropsicon. Canonical serialization avoids false drift. - Concurrency: saves carry an
if_matchguard hash; a stale save is refused with the current hash. - Diagnostics:
vx-framework/get-config-status(groups,keys,states,only_drifted,summary),vx-framework/get-config-conflicts,vx-framework/get-config-diff.