After 8+ years building WordPress sites for agencies and enterprise clients, I’ve refined my developer tools stack down to the essentials that actually move the needle. This isn’t another “50 amazing tools” listicle – these are the battle-tested tools I use daily on real client projects, from custom Gutenberg blocks to complex headless implementations.
Every tool on this list earns its place by solving specific problems I encounter regularly. No fluff, no affiliate link padding – just the honest toolkit that keeps me productive and my clients happy in 2025.
Local Development Environment: The Foundation
Your local dev environment sets the tone for everything else. After trying Docker, XAMPP, MAMP, and various other solutions, I’ve settled on Local by Flywheel for most projects, with specific exceptions I’ll explain.
Local by Flywheel: The Reliable Workhorse
Local handles 90% of my WordPress development needs without fuss. The one-click WordPress installs, built-in SSL, and easy domain management make it perfect for rapid prototyping and client work. Here’s my typical setup process:
# My standard Local site creation workflow
# 1. Create new site with these specs:
# - PHP 8.1+ (matching production)
# - MySQL 8.0
# - Nginx (faster than Apache for dev)
# 2. Immediately configure wp-config.php additions
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);
define('SCRIPT_DEBUG', true);
define('SAVEQUERIES', true);
# 3. Set up SSL and trusted certificate
# Local handles this automatically, but verify it works
# This prevents HTTPS issues when testing API calls
The real power comes from Local’s add-ons. I always install the WP-CLI add-on immediately – it’s essential for database operations, plugin management, and custom scripts.
When I Use Docker Instead
For complex projects requiring specific server configurations or when working with teams that need identical environments, I switch to Docker. Here’s my WordPress Docker Compose setup that mirrors typical production environments:
version: '3.8'
services:
wordpress:
image: wordpress:6.4-php8.2-apache
restart: always
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
WORDPRESS_DEBUG: 1
volumes:
- ./wp-content:/var/www/html/wp-content
- ./uploads.ini:/usr/local/etc/php/conf.d/uploads.ini
depends_on:
- db
db:
image: mysql:8.0
restart: always
environment:
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
MYSQL_RANDOM_ROOT_PASSWORD: '1'
volumes:
- db_data:/var/lib/mysql
phpmyadmin:
image: phpmyadmin/phpmyadmin
restart: always
ports:
- "8081:80"
environment:
PMA_HOST: db
PMA_PORT: 3306
volumes:
db_data:
# uploads.ini content:
# file_uploads = On
# memory_limit = 512M
# upload_max_filesize = 512M
# post_max_size = 512M
# max_execution_time = 600
This setup gives me complete control over the environment and ensures consistency across team members and deployment environments.
Code Editor and Development Tools
Visual Studio Code remains my editor of choice, but the magic is in the configuration. After years of tweaking, here’s my essential extension stack and settings that specifically benefit WordPress development.
Essential VS Code Extensions for WordPress
- PHP Intelephense: Superior PHP intellisense and error detection
- WordPress Hooks Intellisense: Autocomplete for WordPress actions and filters
- Bracket Pair Colorizer 2: Essential for PHP’s nested array structures
- GitLens: Inline git blame and history navigation
- REST Client: Test WordPress REST API endpoints directly in VS Code
- Thunder Client: Lightweight Postman alternative for API testing
- Auto Rename Tag: Automatically renames paired HTML/XML tags
- Path Intellisense: Autocomplete for file paths in require/include statements
My VS Code settings.json includes WordPress-specific configurations that save hours of debugging:
{
"php.suggest.basic": false,
"php.validate.enable": false,
"intelephense.files.associations": [
"*.php",
"*.phtml",
"*.inc"
],
"intelephense.files.exclude": [
"**/node_modules/**",
"**/vendor/**/*.php",
"**/wp-admin/**",
"**/wp-includes/**"
],
"intelephense.stubs": [
"apache",
"bcmath",
"bz2",
"calendar",
"com_dotnet",
"Core",
"ctype",
"curl",
"date",
"dba",
"dom",
"enchant",
"exif",
"fileinfo",
"filter",
"ftp",
"gd",
"hash",
"iconv",
"imap",
"interbase",
"intl",
"json",
"ldap",
"libxml",
"mbstring",
"mcrypt",
"mysql",
"mysqli",
"oci8",
"odbc",
"openssl",
"pcntl",
"pcre",
"PDO",
"pdo_ibm",
"pdo_mysql",
"pdo_pgsql",
"pdo_sqlite",
"pgsql",
"Phar",
"posix",
"pspell",
"readline",
"recode",
"Reflection",
"regex",
"session",
"SimpleXML",
"soap",
"sockets",
"sodium",
"SPL",
"sqlite3",
"standard",
"superglobals",
"sysvsem",
"sysvshm",
"tokenizer",
"xml",
"xmlreader",
"xmlrpc",
"xmlwriter",
"xsl",
"Zend OPcache",
"zip",
"zlib",
"wordpress"
],
"editor.formatOnSave": true,
"[php]": {
"editor.defaultFormatter": "bmewburn.vscode-intelephense-client",
"editor.tabSize": 4
},
"files.associations": {
"*.php": "php",
"*.inc": "php",
"*.module": "php",
"*.theme": "php"
}
}
Database Management and Migration Tools
Database work is inevitable in WordPress development. Whether you’re debugging user data, optimizing queries, or migrating content between environments, having the right tools makes the difference between a 5-minute task and a 2-hour nightmare.
TablePlus: The Database GUI That Actually Works
TablePlus replaced phpMyAdmin in my workflow entirely. It’s fast, has excellent WordPress-specific features, and handles large databases without choking. The query editor includes syntax highlighting and auto-completion for MySQL, which catches errors before execution.
For WordPress-specific tasks, I keep these queries saved as snippets in TablePlus:
-- Find all posts with specific meta key
SELECT p.ID, p.post_title, pm.meta_value
FROM wp_posts p
INNER JOIN wp_postmeta pm ON p.ID = pm.post_id
WHERE pm.meta_key = '_custom_field_name'
AND p.post_status = 'publish';
-- Clean up WordPress transients (performance boost)
DELETE FROM wp_options
WHERE option_name LIKE '_transient_%'
OR option_name LIKE '_site_transient_%';
-- Find large database tables
SELECT
table_name AS 'Table',
ROUND(((data_length + index_length) / 1024 / 1024), 2) AS 'Size (MB)'
FROM information_schema.TABLES
WHERE table_schema = DATABASE()
ORDER BY (data_length + index_length) DESC;
-- Find unused media files
SELECT p.ID, p.post_title, p.guid
FROM wp_posts p
WHERE p.post_type = 'attachment'
AND p.ID NOT IN (
SELECT DISTINCT pm.meta_value
FROM wp_postmeta pm
WHERE pm.meta_key = '_thumbnail_id'
AND pm.meta_value IS NOT NULL
)
AND p.post_parent = 0;
WP-CLI: The Swiss Army Knife
WP-CLI handles tasks that would be painful through the WordPress admin. I use it daily for database operations, content migration, and plugin management. Here are my most-used commands that every WordPress developer should memorize:
# Database operations
wp db export backup-$(date +%Y%m%d-%H%M%S).sql
wp db import production-backup.sql
wp search-replace 'https://oldsite.com' 'https://newsite.com' --dry-run
# Plugin and theme management
wp plugin list --status=active
wp plugin install advanced-custom-fields --activate
wp theme install twentytwentyfour --activate
# User management
wp user create developer dev@example.com --role=administrator --user_pass=temp123
wp user list --role=administrator
# Content operations
wp post list --post_status=draft --format=table
wp post delete $(wp post list --post_status=trash --format=ids)
wp media regenerate --yes
# Cache and optimization
wp cache flush
wp transient delete --all
wp option get active_plugins
# Custom field operations
wp post meta get 123 _custom_field
wp post meta update 123 _custom_field "new value"
# Multisite operations
wp site list
wp --url=subsite.multisite.com post list
Testing and Debugging Arsenal
Testing isn’t optional anymore. Whether you’re building custom blocks, REST API endpoints, or complex themes, having solid testing tools prevents embarrassing bugs and saves client relationships.
Playwright: End-to-End Testing That Actually Works
Playwright has become my go-to for E2E testing WordPress sites. It’s more reliable than Selenium and easier to set up than Cypress for WordPress-specific workflows. Here’s a practical example testing a custom Gutenberg block:
// tests/custom-block.spec.js
const { test, expect } = require('@playwright/test');
test.describe('Custom Testimonial Block', () => {
test.beforeEach(async ({ page }) => {
// Login to WordPress admin
await page.goto('/wp-admin');
await page.fill('#user_login', 'admin');
await page.fill('#user_pass', 'password');
await page.click('#wp-submit');
// Create new post
await page.goto('/wp-admin/post-new.php');
await page.waitForSelector('.editor-post-title');
});
test('should add and configure testimonial block', async ({ page }) => {
// Add block via inserter
await page.click('.edit-post-header-toolbar__inserter-toggle');
await page.fill('.block-editor-inserter__search-input', 'testimonial');
await page.click('[data-type="custom/testimonial"]');
// Configure block settings
await page.fill('.testimonial-name input', 'John Smith');
await page.fill('.testimonial-title input', 'CEO, Example Corp');
await page.fill('.testimonial-content textarea', 'This product changed our business completely.');
// Verify block renders correctly in editor
const testimonialBlock = page.locator('.wp-block-custom-testimonial');
await expect(testimonialBlock).toBeVisible();
await expect(testimonialBlock.locator('.testimonial-name')).toContainText('John Smith');
// Save and preview
await page.click('.editor-post-publish-panel__toggle');
await page.click('.editor-post-publish-button');
// Check frontend rendering
await page.click('.post-publish-panel__postpublish-header a');
const frontendTestimonial = page.locator('.testimonial-wrapper');
await expect(frontendTestimonial).toBeVisible();
await expect(frontendTestimonial).toContainText('John Smith');
await expect(frontendTestimonial).toContainText('CEO, Example Corp');
});
test('should validate required fields', async ({ page }) => {
// Add block without filling required fields
await page.click('.edit-post-header-toolbar__inserter-toggle');
await page.fill('.block-editor-inserter__search-input', 'testimonial');
await page.click('[data-type="custom/testimonial"]');
// Try to save without required content
await page.click('.editor-post-publish-panel__toggle');
// Should show validation error
const errorMessage = page.locator('.testimonial-error');
await expect(errorMessage).toBeVisible();
await expect(errorMessage).toContainText('Name and testimonial content are required');
});
});
This test covers the full workflow from adding a block to verifying frontend output. I run these tests before every deployment to catch regressions early.
Query Monitor: The WordPress Debug Superhero
Query Monitor is the first plugin I install on any development site. It reveals database queries, hook executions, HTTP requests, and PHP errors in a way that actually helps you fix problems quickly.
The real power comes from understanding what to look for. Here are the Query Monitor tabs I check regularly and what red flags to watch for:
- Database Queries: Look for duplicate queries (indicates missing caching) and slow queries (>0.1s)
- Hooks & Actions: Identify which plugins are adding processing overhead
- HTTP Requests: Catch external API calls that might be slowing page loads
- Scripts & Styles: Find unused CSS/JS files that can be removed
- Conditionals: Verify that your conditional logic is working correctly
Version Control and Deployment Pipeline
A solid Git workflow and deployment pipeline saves more time than any other optimization. After managing dozens of WordPress projects, I’ve settled on tools and workflows that minimize human error and maximize team productivity.
Git Workflow for WordPress Projects
WordPress presents unique challenges for version control – you don’t want to track core files, uploads, or database content, but you do need to manage themes, plugins, and configuration. Here’s my standard .gitignore that handles WordPress properly:
# WordPress core files
/wp-admin/
/wp-includes/
/wp-*.php
/index.php
/xmlrpc.php
/readme.html
/license.txt
# WordPress config
wp-config.php
wp-config-local.php
# Uploads and cache
/wp-content/uploads/
/wp-content/cache/
/wp-content/backups/
/wp-content/upgrade/
/wp-content/w3tc-config/
# Plugin and theme dependencies
/wp-content/plugins/hello.php
/wp-content/plugins/akismet/
/wp-content/themes/twenty*/
# Build and development files
node_modules/
npm-debug.log
.DS_Store
Thumbs.db
.env
.env.local
# IDE files
.vscode/
.idea/
*.swp
*.swo
# Build outputs (if using build tools)
/wp-content/themes/custom-theme/dist/
/wp-content/themes/custom-theme/build/
# Logs
*.log
error_log
debug.log
For branch management, I use a simplified Git Flow approach with these branch types:
- main: Production-ready code, only updated via pull requests
- develop: Integration branch for features, deployed to staging
- feature/[name]: Individual features or bug fixes
- hotfix/[name]: Critical fixes that need immediate deployment
WP Engine Git Push: Deployment Made Simple
For clients on WP Engine, I use their Git Push deployment system. It’s not perfect, but it’s reliable and integrates well with their platform. The key is setting up proper build hooks for projects using modern build tools.
Here’s my standard WP Engine deployment configuration in the project root:
# .wpengine-deploy-hooks.yml
# This file configures build steps during deployment
before_build:
- echo "Starting deployment to WP Engine"
- echo "Node version: $(node --version)"
- echo "NPM version: $(npm --version)"
build:
# Install dependencies
- cd wp-content/themes/custom-theme && npm ci
# Run build process
- cd wp-content/themes/custom-theme && npm run build:production
# Install Composer dependencies (if using)
- cd wp-content/themes/custom-theme && composer install --no-dev --optimize-autoloader
# Clean up development files
- find wp-content/themes/custom-theme -name "node_modules" -type d -exec rm -rf {} +
- find wp-content/themes/custom-theme -name ".git" -type d -exec rm -rf {} +
- rm -rf wp-content/themes/custom-theme/src/
- rm -rf wp-content/themes/custom-theme/webpack.config.js
- rm -rf wp-content/themes/custom-theme/package*.json
after_build:
- echo "Deployment completed successfully"
- echo "Build artifacts cleaned up"
This configuration ensures that build tools run during deployment, but development files don’t make it to production servers.
Performance and Monitoring Tools
Performance isn’t just about page load times – it’s about developer experience, debugging efficiency, and client satisfaction. These tools help me identify and fix performance issues before they become problems.
New Relic: Production Performance Monitoring
New Relic gives me real-time insights into how WordPress sites perform in production. Unlike synthetic testing tools, it shows actual user experience data and helps identify performance bottlenecks that only appear under real traffic loads.
The WordPress-specific insights I monitor include:
- Database query performance: Slow queries that need optimization
- Plugin impact: Which plugins consume the most resources
- API response times: REST API and admin-ajax.php performance
- Error rates: PHP errors and failed requests
- Apdex scores: Overall user satisfaction with response times
I set up custom alerts for WordPress-specific issues like database connection failures, memory limit errors, and unusually high admin-ajax.php usage – all signs of common WordPress problems.
WebPageTest: Deep Performance Analysis
WebPageTest provides the most detailed performance analysis available. I use it during development to catch performance issues before they reach production. The filmstrip view and waterfall charts reveal exactly when and why pages load slowly.
For WordPress sites, I focus on these metrics:
- First Contentful Paint (FCP): Should be under 2 seconds
- Largest Contentful Paint (LCP): Critical for Core Web Vitals, target under 2.5s
- Cumulative Layout Shift (CLS): Particularly important for sites with ads or dynamic content
- Time to Interactive (TTI): When the page becomes fully interactive
- Total Blocking Time: How long the main thread is blocked
API Development and Testing
Modern WordPress development involves a lot of API work – whether you’re building headless sites, integrating third-party services, or creating custom REST endpoints. Having the right API tools makes the difference between productive development and debugging hell.
Insomnia: API Client That Understands WordPress
Insomnia has replaced Postman in my workflow for WordPress API development. It handles WordPress authentication better and has excellent environment management for testing across development, staging, and production.
Here’s my standard WordPress REST API testing setup in Insomnia:
// Environment Variables (Development)
{
"base_url": "https://myproject.local",
"username": "admin",
"password": "admin",
"jwt_token": "",
"application_password": "xxxx xxxx xxxx xxxx"
}
// JWT Authentication Request
POST {{base_url}}/wp-json/jwt-auth/v1/token
Content-Type: application/json
{
"username": "{{username}}",
"password": "{{password}}"
}
// Application Password Authentication (WordPress 5.6+)
GET {{base_url}}/wp-json/wp/v2/posts
Authorization: Basic {{base64(username:application_password)}}
// Custom REST Endpoint Test
POST {{base_url}}/wp-json/custom/v1/process-form
Content-Type: application/json
Authorization: Bearer {{jwt_token}}
{
"form_data": {
"name": "John Doe",
"email": "john@example.com",
"message": "Test message from API"
},
"form_id": 123,
"nonce": "{{wp_nonce}}"
}
// GraphQL Query (if using WPGraphQL)
POST {{base_url}}/graphql
Content-Type: application/json
{
"query": "query GetPosts($first: Int!) { posts(first: $first) { nodes { id title content } } }",
"variables": {
"first": 10
}
}
I keep collections for each project with common WordPress API operations – posts, users, custom post types, and any custom endpoints. This saves hours of setup time when switching between projects.
Build Tools and Asset Management
Modern WordPress development requires build tools for SASS compilation, JavaScript bundling, and asset optimization. The tools have evolved significantly, and choosing the right stack affects both development speed and build performance.
Vite: The Modern Build Tool
Vite has become my preferred build tool for WordPress projects that need modern JavaScript and CSS processing. It’s faster than Webpack for development and produces optimized production builds.
Here’s my standard Vite configuration for WordPress theme development:
// vite.config.js
import { defineConfig } from 'vite';
import { resolve } from 'path';
export default defineConfig({
root: 'src',
base: '/wp-content/themes/custom-theme/dist/',
build: {
outDir: '../dist',
emptyOutDir: true,
manifest: true,
rollupOptions: {
input: {
main: resolve(__dirname, 'src/js/main.js'),
admin: resolve(__dirname, 'src/js/admin.js'),
editor: resolve(__dirname, 'src/js/editor.js'),
style: resolve(__dirname, 'src/scss/style.scss'),
'admin-style': resolve(__dirname, 'src/scss/admin.scss')
},
output: {
entryFileNames: 'js/[name].[hash].js',
chunkFileNames: 'js/[name].[hash].js',
assetFileNames: (assetInfo) => {
const extType = assetInfo.name.split('.').pop();
if (/png|jpe?g|svg|gif|tiff|bmp|ico/i.test(extType)) {
return 'images/[name].[hash][extname]';
}
if (/woff2?|eot|ttf|otf/i.test(extType)) {
return 'fonts/[name].[hash][extname]';
}
return 'css/[name].[hash][extname]';
},
},
},
},
server: {
host: 'localhost',
port: 3000,
cors: true,
hmr: {
host: 'localhost',
port: 3000
}
},
css: {
devSourcemap: true,
preprocessorOptions: {
scss: {
additionalData: '@import "variables"; @import "mixins";',
includePaths: [resolve(__dirname, 'src/scss/abstracts')]
}
}
}
});
// package.json scripts
{
"scripts": {
"dev": "vite",
"build": "vite build",
"build:production": "vite build --mode production",
"preview": "vite preview",
"watch": "vite build --watch"
}
}
This setup provides hot module reloading during development and generates optimized, hashed assets for production. The manifest.json file makes it easy to enqueue the correct versioned assets in WordPress.
Key Takeaways for Your 2025 WordPress Toolkit
Building an effective WordPress development toolkit isn’t about having the most tools – it’s about having the right tools that work together seamlessly. After years of testing different combinations, these tools form a cohesive system that handles everything from initial development to production monitoring.
- Local by Flywheel + Docker: Cover 100% of development scenarios with these two environment options
- VS Code + WordPress-specific extensions: Essential for productive PHP and JavaScript development
- TablePlus + WP-CLI: Handle all database operations efficiently
- Playwright + Query Monitor: Catch bugs before they reach production
- Git + WP Engine Deploy: Reliable, repeatable deployments
- New Relic + WebPageTest: Monitor and optimize performance continuously
- Insomnia: Essential for API development and testing
- Vite: Modern build tooling that actually improves development speed
The key insight after years of WordPress development: invest time in setting up your tools properly once, then reuse those configurations across projects. Every hour spent optimizing your development workflow pays dividends across every project you build.
Start with the foundation – local development environment and code editor – then add tools as you encounter specific problems. Don’t try to implement everything at once. Build your toolkit gradually, focusing on tools that solve actual pain points in your current workflow.
Most importantly, document your configurations and keep them in version control. When you land that dream client project with tight deadlines, you’ll be grateful for the setup scripts and configuration files that let you hit the ground running.
