I spent an embarrassing amount of time early in my WordPress career refreshing a page and seeing nothing change. The CSS was right, the theme.json values were right, but the output was stale. The problem was caching I didn’t know existed.
WordPress 6.3 introduced WP_DEVELOPMENT_MODE to fix exactly this. It tells WordPress what kind of development you’re doing and disables the caches that get in the way.
TLDR
Add define( 'WP_DEVELOPMENT_MODE', 'theme' ); to wp-config.php to disable theme.json caching during theme development. Use 'plugin' for plugin work, 'core' for WordPress core contributions, or 'all' to turn on every mode at once. WordPress doesn’t switch it off in production for you, so remove it (or set it to '') before you deploy.
What it does
WP_DEVELOPMENT_MODE accepts four values plus an empty string:
'theme'skips thetheme.json, global styles, and block pattern caches. Changes totheme.json, style variations, and pattern files show up on the next page load.'plugin'signals that you’re working on a plugin. Core itself doesn’t change anything for this mode yet. It’s a flag that your own code, or another plugin, can check withwp_is_development_mode( 'plugin' ).'core'is for contributing to WordPress itself. In core today it skips one cache: the list of core block CSS files.'all'matches every mode check, so theme, plugin, and core all count as on. Use this when you’re working across multiple areas or just want all development caches out of the way.''(empty string) is the default. No development mode, all caches active. This is what production sites should use.
The biggest practical impact today is theme.json caching. WordPress caches the resolved output of theme.json for performance. During development, that cache means your changes don’t appear until the cache expires or gets flushed. Setting the mode to 'theme' or 'all' skips that cache entirely.
I checked where core actually reads the mode in WordPress 7.1.4, so you know what you’re turning on:
wp-includes/global-styles-and-settings.phpskips its cached global settings, stylesheet, and SVG filters in'theme'mode.wp-includes/class-wp-theme.phpskips the cached list of block pattern files in'theme'mode.wp-includes/blocks/index.phpskips thewp_core_block_css_filestransient in'core'mode.
That’s the full list. Nothing in core checks for 'plugin'.
How to set it
Open wp-config.php and add one line before “That’s all, stop editing!”:
For theme development:
define( 'WP_DEVELOPMENT_MODE', 'theme' );
For plugin development:
define( 'WP_DEVELOPMENT_MODE', 'plugin' );
For everything at once:
define( 'WP_DEVELOPMENT_MODE', 'all' );
Environment-aware setup
If your project uses different configs for different environments, tie it to WP_ENVIRONMENT_TYPE so the mode only activates outside production:
if ( defined( 'WP_ENVIRONMENT_TYPE' ) && 'production' !== WP_ENVIRONMENT_TYPE ) {
define( 'WP_DEVELOPMENT_MODE', 'all' );
}
Or read from an environment variable:
$env = getenv( 'WP_ENVIRONMENT_TYPE' );
if ( $env && 'production' !== $env ) {
define( 'WP_DEVELOPMENT_MODE', 'all' );
}
Either approach keeps the mode off in production automatically.
How to check if it’s working
Two ways.
In WordPress 6.3+, go to Tools > Site Health > Info > WordPress Constants. The current value of WP_DEVELOPMENT_MODE shows up there.
In code, use wp_is_development_mode():
if ( wp_is_development_mode( 'theme' ) ) {
// Theme-specific development logic.
}
This function returns true if the mode matches, or always true if the mode is set to 'all'.
Common mistakes
Defining it too late. The constant needs to be set before WordPress initializes. Put it near the top of wp-config.php, right after the database settings. If you define it after WordPress loads, it won’t have any effect.
Leaving it on in production. Development mode disables caches that exist for good reason on live sites. theme.json caching alone makes a measurable difference on page load times for block themes. Always remove or empty the constant before deploying.
Using 'core' when you don’t mean it. The 'core' mode is for people contributing to WordPress itself. For building themes or plugins, stick with 'theme', 'plugin', or 'all'.
Expecting production to switch it off. It won’t. wp_get_development_mode() in wp-includes/load.php reads the constant and nothing else. It never looks at WP_ENVIRONMENT_TYPE, so a site set to production with the mode set to 'theme' still skips the caches. That’s why the environment-aware setup above is worth the two extra lines.
A typo in the value. The same function only accepts 'core', 'plugin', 'theme', 'all', or ''. Anything else, like 'themes' or 'Theme', is quietly reset to '', with no warning. Site Health won’t catch this, because it prints the constant exactly as you typed it. If the caches still seem stuck, wp_get_development_mode() returns the value core actually uses.
Relationship to other debug constants
WP_DEVELOPMENT_MODE is separate from WP_DEBUG. WP_DEBUG controls PHP error reporting. WP_DEVELOPMENT_MODE controls development-specific caching behavior. You’ll often want both enabled during development, but they do different things.
Similarly, SCRIPT_DEBUG forces WordPress to load unminified JavaScript and CSS files. It’s complementary to WP_DEVELOPMENT_MODE, not a replacement.
A typical development wp-config.php might include all three:
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );
define( 'SCRIPT_DEBUG', true );
define( 'WP_DEVELOPMENT_MODE', 'all' );
References
- Configuring development mode in 6.3 (Make WordPress Core).
wp_get_development_mode()(WordPress Developer Resources).wp_is_development_mode()(WordPress Developer Resources).