Skip to content

Development Setup & Dev Mode

Set up a local development environment and run the ThemePlus build pipeline.

Set up a local development environment and run the ThemePlus build pipeline.

Overview

ThemePlus uses a hybrid build architecture β€” Vite handles SCSS compilation with HMR in development, and webpack via @wordpress/scripts handles the React admin panel and generates the WordPress dependency manifest. Both pipelines run in parallel during development.

This article is for contributors who want to modify ThemePlus source files. Theme developers integrating ThemePlus into a theme do not need any build tooling.

Requirements

ToolMinimum Version
Node.js20.19+ or 22.12+
npm9.0.0
PHP8.0
WordPress6.8
Local WordPress environmentLocal by Flywheel recommended

Vite 7 requires Node.js 20.19+ or 22.12+ β€” Node.js 18 reached end-of-life in April 2025 and is no longer supported. Use node --version to check your current version and upgrade via nodejs.org if needed.

Repository Setup

1. Clone into your plugins folder

πŸ“„<code>bash
cd wp-content/plugins
git clone https://github.com/fronttheme/themeplus.git
cd themeplus

2. Install dependencies

npm install

3. Enable dev mode constants in wp-config.php

πŸ“„<code>php
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );
define( 'WP_ENVIRONMENT_TYPE', 'local' );
define( 'THEMEPLUS_DEV', true );

THEMEPLUS_DEV must be defined in wp-config.php β€” not in functions.php. It must be a boolean true, not a string.

4. Activate the plugin

Go to Plugins β†’ Installed Plugins in the WordPress admin and activate ThemePlus. Then activate the ThemePlus Demo theme β€” this gives you a full field registration to develop against.

Running Dev Mode

Dev mode requires two terminal processes running simultaneously β€” one for each build pipeline.

Terminal 1 β€” Vite (SCSS with HMR):

npm run dev

Starts the Vite dev server on port 3000. Watches src/scss/ for changes and hot-reloads the admin panel styles without a page reload.

Terminal 2 β€” wp-scripts (React/JSX):

npm run blocks:start

Starts the webpack watcher. Recompiles src/js/admin/ on save and outputs assets/js/admin.js + assets/js/admin.asset.php.

Both watchers must be running simultaneously for all changes to be reflected β€” Vite handles styles, wp-scripts handles JavaScript.

Build Architecture

ToolHandlesInputOutput
ViteSCSS β†’ CSS (with HMR in dev)src/scss/admin.scssassets/css/admin.css
webpack / wp-scriptsReact/JSX β†’ JS + dependency manifestsrc/js/admin/index.jsassets/js/admin.js + assets/js/admin.asset.php

admin.asset.php is generated automatically by wp-scripts β€” it contains a content-hash version string and the full WordPress dependency array (wp-componentswp-elementwp-api-fetchwp-i18nreact). The plugin reads this file in production for correct cache busting.

Available Scripts

ScriptCommandDescription
Dev β€” Vitenpm run devStarts Vite dev server with HMR for SCSS
Dev β€” Reactnpm run blocks:startStarts webpack watcher for JS/React
Build β€” Vitenpm run buildProduction build of SCSS β†’ CSS
Build β€” Reactnpm run blocks:buildProduction build of React β†’ JS
Generate .potnpm run potRegenerates languages/themeplus.pot
Packagenpm run packageRuns both builds + pot + creates themeplus.zip

Project Structure

themeplus/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ js/admin/               # React admin panel source
β”‚   β”‚   β”œβ”€β”€ components/
β”‚   β”‚   β”‚   β”œβ”€β”€ Fields/         # One file per field type (30 components)
β”‚   β”‚   β”‚   β”œβ”€β”€ Common/         # FieldRenderer, Dialog, Select, SearchResults
β”‚   β”‚   β”‚   β”œβ”€β”€ Layout/         # Sidebar, Header, Body, Footer, MainWrapper
β”‚   β”‚   β”‚   β”œβ”€β”€ Sections/       # Import/Export, Custom Font Uploader
β”‚   β”‚   β”‚   └── DevPanel/       # Developer Panel components
β”‚   β”‚   β”œβ”€β”€ context/            # React Context β€” Settings, Theme
β”‚   β”‚   β”œβ”€β”€ hooks/              # Custom React hooks
β”‚   β”‚   β”œβ”€β”€ services/           # Google Fonts and Custom Fonts API services
β”‚   β”‚   β”œβ”€β”€ utils/              # fieldHelpers.js β€” conditional logic evaluation
β”‚   β”‚   └── App.jsx             # Root application component
β”‚   └── scss/                   # SCSS source β€” 7-1 modular architecture
β”œβ”€β”€ assets/                     # Compiled output (do not edit directly)
β”‚   β”œβ”€β”€ css/admin.css           # Built by Vite
β”‚   β”œβ”€β”€ js/admin.js             # Built by wp-scripts
β”‚   β”œβ”€β”€ js/admin.asset.php      # wp-scripts dependency manifest
β”‚   └── fonts/fontawesome/      # Bundled FontAwesome 7
β”œβ”€β”€ includes/                   # PHP framework classes
β”‚   β”œβ”€β”€ classes/core/           # Core framework classes
β”‚   β”œβ”€β”€ classes/custom-fonts/   # Custom Fonts module
β”‚   β”œβ”€β”€ config/                 # sample-config.php, default-config.php
β”‚   └── functions/              # Public helper functions
β”œβ”€β”€ languages/                  # themeplus.pot + translations
β”œβ”€β”€ themeplus.php               # Plugin entry point
β”œβ”€β”€ uninstall.php               # Clean removal routine
β”œβ”€β”€ package.json
β”œβ”€β”€ vite.config.mjs
β”œβ”€β”€ webpack.config.js
β”œβ”€β”€ .distignore                 # Files excluded from the release ZIP
└── .gitignore

Building for Production

Run all build steps in order:

npm run build        # SCSS β†’ assets/css/admin.css
npm run blocks:build # React β†’ assets/js/admin.js + admin.asset.php
npm run pot          # Regenerate languages/themeplus.pot
npm run package      # Creates package/themeplus.zip

Or run everything in one command:

npm run package

npm run package runs both builds and the pot generation, then creates a clean ZIP at package/themeplus.zip excluding source files, dev tooling, and git artifacts per .distignore. This ZIP is the distributable plugin β€” attach it to a GitHub Release or upload to WordPress.org.

What’s excluded from the package ZIP

The .distignore file controls what is excluded:

src/
node_modules/
package.json
package-lock.json
vite.config.mjs
webpack.config.js
.git/
.gitignore
.gitattributes
.distignore
.github/
*.map
README.md
CHANGELOG.md
CONTRIBUTING.md
SECURITY.md

Dev Mode Behaviors

When dev mode is active (see detection logic below), ThemePlus enables:

  • Vite HMR β€” start npm run dev for SCSS hot module replacement in the admin panel
  • Developer Panel β€” appears as the last sidebar section showing field metadata, values, and code snippets
  • Console logging β€” React panel logs state changes, save events, and conditional logic evaluations
  • Error boundaries β€” React component errors show a detailed stack trace overlay instead of silently failing
  • Dev-only REST endpoint β€” /wp-json/themeplus/v1/dev-panel becomes available

Dev Mode Detection

ThemePlus detects dev mode automatically using this priority order:

  1. THEMEPLUS_DEV constant β€” explicit override (highest priority). true forces dev mode on, false forces it off regardless of other conditions
  2. WP_DEBUG = true in wp-config.php
  3. WP_ENVIRONMENT_TYPE = 'local' β€” set automatically by Local by Flywheel

You do not need to configure dev mode in your theme’s themeplus_framework_config() β€” it is detected automatically behind the scenes.

Adding a New Field Type

  1. Create the React component in src/js/admin/components/Fields/MyNewField.jsx
  2. Export it from src/js/admin/components/Fields/index.js
  3. Register it in src/js/admin/components/Common/FieldRenderer.jsx
  4. Add SCSS in src/scss/components/_my-new-field.scssand import in src/scss/admin.scss
  5. Add a case in ThemePlus_Sanitizer::sanitize_field()for the new type
  6. Run npm run dev + npm run blocks:start, open the ThemePlus Demo theme, and verify the field appears correctly in the All Values panel and Developer Panel

See CONTRIBUTING.md for the full six-step guide.

Notes

  • Always run npm run package before tagging a release β€” the compiled assets/ directory is committed to the repository and must match the current source.
  • Never set THEMEPLUS_DEV = true in a production or publicly distributed theme β€” it exposes debug information and loads development assets.
  • The Vite dev server (npm run dev) runs on port 3000 and handles only HMR for assets β€” WordPress page loads still go through your local server as normal.
  • If you want to run both watchers in one terminal: npx concurrently "npm run dev" "npm run blocks:start"
  • The .pot file in languages/ is a committed source artifact β€” regenerate it with npm run pot whenever you add or change translatable strings, not as part of every build.

On This Page