Description
Compile SCSS (Sass) to CSS straight from the WordPress admin. Theme SCSS Compiler manages as many SCSS CSS file pairs as your theme needs, under Tools Theme SCSS Compiler. It uses the bundled scssphp library, so there is no Node.js, no build step and no command line. SCSS is the modern Sass syntax: plain CSS plus nesting, variables and @import.
Features
- Multiple file pairs – as many SCSS CSS pairs as your theme needs, paths relative to the active theme.
- Frontend or Admin per pair – each pair enqueues on
wp_enqueue_scriptsoradmin_enqueue_scripts. - Per-file versioning – every pair has its own version, applied through the
style_loader_srcfilter. Your theme files stay untouched. - Smart change detection – a version only bumps when that pair’s compiled CSS really changed.
@import-aware recompile – every partial (@import,@use,@forward) is tracked. Edit a partial and the next admin page load recompiles.- Compressed or expanded output – minified for production, readable for development.
- Auto-compile – missing or stale CSS is rebuilt on the next admin page load, so a deploy never leaves you with unstyled pages.
- Auto-enqueue – the plugin calls
wp_enqueue_style()for each pair and skips files already registered, so output is never duplicated. - Manual compile button – one click, live feedback, persistent error display.
- Concurrent-compile lock – two admins compiling at once can’t corrupt the CSS.
- Code-first config – set every option as a PHP constant in
wp-config.php, your theme, or.env/ Bedrock. - Admin-only – every endpoint needs
manage_options. Change that with thetscsscompiler_capabilityfilter. - Modern and accessible – PHP 8.1+, WCAG 2.1 AA admin UI, German translation included.
Privacy / GDPR
This plugin makes no external HTTP requests, sets no cookies, runs no telemetry and does not track users. All processing happens locally on your server. The bundled libraries (scssphp, league/uri, symfony/filesystem, PSR HTTP interfaces) are MIT licensed and GPL-compatible; their source is included in the plugin’s vendor/ directory.
Screenshots

Settings page under Tools Theme SCSS Compiler in production-default mode — multiple file pairs with per-pair version and Frontend/Admin context, auto-compile and auto-enqueue enabled. 
Same page in development workflow — Expanded output for readable CSS, manual-compile mode with success feedback after a Compile-now click.
Installation
- Upload the
theme-scss-compilerfolder to/wp-content/plugins/. - Activate the plugin in Plugins.
- Go to Tools Theme SCSS Compiler and set your SCSS / CSS paths and the per-pair context.
- Click Compile now, or just load any admin page. Auto-compile is on by default and builds the CSS the first time.
Prefer code-based configuration? See the FAQ on constants for wp-config.php, your theme, or .env / Bedrock.
FAQ
-
Which SCSS version does this support?
-
The plugin bundles scssphp 2.1. It supports the SCSS you write day to day: nesting, variables, mixins, functions and
@import/@use/@forward. scssphp is a PHP port of Sass, not a byte-for-byte copy of Dart Sass, so a few Dart-only built-in functions are not available. For normal theme stylesheets that almost never matters. Check the compiled CSS once after you move a theme over. -
I’m new to SCSS. What does it actually look like?
-
SCSS is CSS with a few extras. Every valid CSS file is already valid SCSS, so you can start small.
Nesting. Write child selectors inside their parent instead of repeating it:
// SCSS .card { padding: 1rem; a { color: rebeccapurple; } } /* compiled CSS */ .card { padding: 1rem; } .card a { color: rebeccapurple; }The
&parent reference. Handy for states like:hoveror an.activeclass:// SCSS .button { background: #0073aa; &:hover { background: #005177; } &.active { background: #003f66; } } /* compiled CSS */ .button { background: #0073aa; } .button:hover { background: #005177; } .button.active { background: #003f66; }Variables. Set a value once, reuse it everywhere:
$brand: #0073aa; a { color: $brand; } .button { background: $brand; }Save the file, open any wp-admin page, and the plugin compiles it to the CSS your theme loads. Full guide: https://sass-lang.com/guide/
-
Does the plugin edit my theme files?
-
No. It never edits your SCSS, your
functions.phpor yourstyle.cssheader. The only file it writes is the compiled CSS target you set for each pair (for exampleassets/css/style.css). That file is overwritten on every compile, so treat it as build output, not something you hand-edit. Cache-busting versions are added at runtime through thestyle_loader_srcfilter, not by rewriting files. -
When does a version actually get bumped?
-
Only when that pair’s compiled CSS differs from the file already on disk. Comment-only edits, or changes that produce identical CSS, do not bump the version. Other pairs keep theirs.
-
How does the per-pair Context (Frontend / Admin) setting work?
-
Each pair has a Context. Frontend pairs are enqueued on
wp_enqueue_scripts(public site only). Admin pairs are enqueued onadmin_enqueue_scripts(wp-admin only). The version filter applies in both. New pairs default to Frontend. -
Who can access the admin page?
-
By default only administrators (the
manage_optionscapability). The menu, the save handler, the AJAX compile endpoint and the auto-compile hook all check it, so Editors and Authors can’t see or use the plugin. To allow another role, use thetscsscompiler_capabilityfilter:add_filter( 'tscsscompiler_capability', static function () { return 'edit_theme_options'; } ); -
Where do the compiled CSS files go, and what if they are missing?
-
Each CSS target is written inside the active theme at the path you set. Commit those files or add them to
.gitignore, your call. With Auto-compile on (the default), every admin page load checks whether each CSS file exists and whether its SCSS source or any@import-ed partial is newer, and rebuilds anything missing or stale. So a fresh deploy orgit pullwithout the compiled CSS won’t leave you with an unstyled site. -
Does it detect changes in `@import`-ed partials?
-
Yes. After each successful compile the plugin records every file scssphp pulled in, including nested
@import/@use/@forwardchains. Auto-compile compares each tracked partial’s modified time against the CSS output. So ifstyle.scssdoes@import "menu-styles";and you only editmenu-styles.scss, the next admin page load recompiles. You don’t have to touchstyle.scss. -
Does compiling ever run on the front end, or for visitors?
-
No. Compiling only happens in wp-admin, for logged-in users who pass the capability check. AJAX and WP-Cron requests are excluded. Visitors are only ever served the already-compiled CSS, so there is no SCSS work on the front end.
-
Where do I see compilation errors?
-
On the Tools Theme SCSS Compiler page. A failed compile stays in a “Last compile error” panel (server paths stripped from the message) until the next successful compile clears it. The Compile now button also reports success or failure live.
-
Can the CSS target be outside the theme?
-
No. Both the SCSS source and the CSS target are resolved relative to the active theme, and any path with
..is rejected. The plugin only reads and writes inside the active theme. -
Does it work with child themes?
-
Yes. Paths resolve against the active stylesheet directory, which is the child theme when one is active. Point the pairs at whichever theme ships the SCSS.
-
Should I let the plugin enqueue my CSS, or do it in `functions.php`?
-
Either works. Auto-enqueue is on by default: the plugin calls
wp_enqueue_style()for each pair on its context, atPHP_INT_MAXpriority, and skips any URL already registered, so it never duplicates output. Want to manage assets yourself? Turn the option off and callwp_enqueue_style()in your theme. -
Can I configure the plugin from code instead of the admin form?
-
Yes. Define
TSCSSCOMPILER_PAIRSand the plugin reads pairs from there instead of the database. The admin form becomes read-only and saving is disabled.define( 'TSCSSCOMPILER_PAIRS', [ [ 'scss_path' => 'assets/scss/style.scss', 'css_path' => 'assets/css/style.css', 'version' => '1.0.0', 'context' => 'frontend' ], [ 'scss_path' => 'assets/scss/style-admin.scss', 'css_path' => 'assets/css/style-admin.css', 'version' => '1.0.0', 'context' => 'admin' ], ] );Toggle the rest individually:
TSCSSCOMPILER_AUTO_COMPILE–true/falseTSCSSCOMPILER_BUMP_VERSION–true/false(note: bumping is a no-op when defined via constant — versions live in your code)TSCSSCOMPILER_AUTO_ENQUEUE–true/falseTSCSSCOMPILER_OUTPUT_STYLE–'compressed'/'expanded'
-
Where can I put the `define()` calls?
-
Three common places:
1.
wp-config.php(loaded first, recommended):define( 'TSCSSCOMPILER_OUTPUT_STYLE', 'compressed' );2. Theme
functions.php(hook intoafter_setup_themeso the constant exists when the plugin reads it):add_action( 'after_setup_theme', static function () { if ( ! defined( 'TSCSSCOMPILER_PAIRS' ) ) { define( 'TSCSSCOMPILER_PAIRS', [ [ 'scss_path' => 'assets/scss/style.scss', 'css_path' => 'assets/css/style.css', 'version' => '1.0.0', 'context' => 'frontend' ], ] ); } } );3.
.env+wp-config.php(Bedrock): -
.env
-
TSCSSCOMPILER_AUTO_ENQUEUE=true
TSCSSCOMPILER_OUTPUT_STYLE=compressed -
wp-config.php (or config/application.php in Bedrock)
-
if ( getenv( ‘TSCSSCOMPILER_AUTO_ENQUEUE’ ) !== false ) {
define( ‘TSCSSCOMPILER_AUTO_ENQUEUE’, filter_var( getenv( ‘TSCSSCOMPILER_AUTO_ENQUEUE’ ), FILTER_VALIDATE_BOOLEAN ) );
}
if ( $style = getenv( ‘TSCSSCOMPILER_OUTPUT_STYLE’ ) ) {
define( ‘TSCSSCOMPILER_OUTPUT_STYLE’, $style );
}Pairs are a nested array and don’t fit in
.env. Define them inwp-config.php(orconfig/application.phpin Bedrock) instead. -
Why do I see a notice “Configured via wp-config.php”?
-
TSCSSCOMPILER_PAIRS is defined somewhere (wp-config, theme, or an
.envbridge). The form is read-only in that state. Edit the source where the constant is defined to make changes. Boolean constants like…_AUTO_COMPILEshow as locked switches too. -
Is the plugin accessible?
-
Yes, the admin UI targets WCAG 2.1 AA: semantic headings, ARIA roles for status and alert regions, keyboard-focusable controls with a visible focus ring, and sufficient colour contrast. Decorative icons are marked
aria-hidden. -
Is there a German translation?
-
Yes, included out of the box. Every admin string, hint and error message is translated (
de_DE).
Reviews
There are no reviews for this plugin.
Contributors & Developers
“Theme SCSS Compiler” is open source software. The following people have contributed to this plugin.
ContributorsTranslate “Theme SCSS Compiler” into your language.
Interested in development?
Browse the code, check out the SVN repository, or subscribe to the development log by RSS.
Changelog
1.0.3
- Compatibility: tested with WordPress 7.0. No code or behaviour changes.
1.0.2
- Fixed: “Compile now” now updates each changed pair’s Version field instantly, without a page reload.
- Documentation: expanded FAQ (beginner SCSS primer, front-end behaviour, error display, git/deploy, theme-relative paths, child themes); tempered the scssphp / Dart Sass wording.
- Synced bundled libraries to the locked versions (no behaviour change).
- No configuration, options or public API changes.
1.0.1
- Fixed: editing an
@imported partial did not always trigger auto-recompile. When the SCSS compiler reported an included file via a non-canonical path (containing..,.or doubled slashes), the recorded dependency was silently discarded and changes to that partial went undetected. Included paths are now collapsed before being stored. - Fixed: on installs where the theme directory is a symlink (e.g. Bedrock-style layouts), dependency tracking failed entirely – the resolved (realpath) source paths never matched the unresolved theme directory, so every dependency was dropped. The theme directory is now resolved consistently for all comparisons.
- Note: both issues affected automatic compilation only. The manual “Compile now” button was never affected, as it compiles unconditionally without consulting the dependency cache.
- No changes to configuration, options or public API.
1.0.0
- Initial release.
- Multiple SCSS CSS pairs with per-pair version and Frontend/Admin context.
@import-aware dependency tracking – every imported partial is recorded; editing a partial alone triggers auto-recompile.- Smart change detection via content comparison – versions only bump on real CSS changes.
- Auto-compile on missing or stale output.
- Auto-enqueue with duplicate detection (runs at
PHP_INT_MAXpriority). - Manual compile button with AJAX feedback.
- Concurrent-compile lock to prevent race conditions on busy multi-admin sites.
- Code-first configuration via
TSCSSCOMPILER_*constants. tscsscompiler_capabilityfilter for granting access to custom roles.- Filesystem writes via WordPress
WP_FilesystemAPI. - WCAG 2.1 AA compliant admin UI.
- German translation included.
- PHP 8.1+ required.
- Bundles scssphp 2.1 (MIT) and dependencies.
