Developer OnboardingDeveloper Stack & Workflow

Developer Stack & Workflow

Developer Stack & Workflow

This is the baseline setup every PixelPress developer works in. It is not service-specific — the same stack underpins a plugin audit, a care-plan fix, and a bespoke build. The technical playbooks (plugin audits, builds, etc.) assume you already work this way; this page is what they assume.

This is for developers only. VAs do not use this setup.

The goal is simple: never lose work, and never be blocked by someone else's server going down. If a host has an outage, you keep working on a local copy and push when they're back. That's the whole point.


The one mental model that makes this click

WordPress is two things: code and content. They travel in opposite directions.

  • Code goes UP. The custom theme and any custom plugins we write live in Git. You edit them locally, commit, and push to the repo. The repo is the source of truth for code.
  • Content/database comes DOWN. Posts, pages, ACF field values, media — all of that lives in the database and the uploads folder on the live or staging site. You pull a fresh copy down to your machine when you need current content. The database is never in Git.

Once that's clear, everything else is just tooling. Code up through Git. Database down from the environment.


The stack

1. Local environment — Local (by WP Engine)

Use Local (localwp.com). It's free, runs on Windows, Mac, and Linux, and spins up a full WordPress site in one click — no Docker, no server config, no editing php.ini by hand.

  • Do not use XAMPP or MAMP. They're per-machine, fragile, and every dev's setup drifts over time. Local gives everyone the same environment, which is what we want across the team.
  • Local manages PHP versions, SSL, mail catching, and the database for you.
  • WP-CLI is built into Local — open the site's shell from inside the app and wp commands just work. No SSH needed for local work.
  • For our WP Engine clients, Local connects directly to the host and can pull a live or staging site down to your machine in a couple of clicks, then push back up. This is the feature that means a host outage never blocks you again.

2. Version control — Git via GitHub Desktop

Start with GitHub Desktop (desktop.github.com), not the command line.

The reason people avoid Git is the terminal, not Git itself. GitHub Desktop reduces the daily loop to: see your changes → write a short message → commit → push. You can branch, pull, and resolve conflicts without ever opening a terminal.

Once you're comfortable, you're welcome to move to the Git CLI — but it's never a requirement, and it's not the entry point. Get the habit first; get fancy later.

3. Repository — GitHub (we have a paid account)

  • One repo per client.
  • The repo lives at the WordPress site root on your machine (wherever Local installed it).
  • You only ever track our custom code: the custom theme (or child theme) and any custom/mu-plugins we write.
  • Everything else is ignored via .gitignore — WordPress core, wp-content/uploads, third-party plugins, default themes, cache. See the sample below.
  • The database is not in the repo. (Worth repeating, because it's the most common point of confusion.)

A typical client repo is small and clean — just wp-content/themes/clientname/ and maybe one custom plugin. That's it.

4. Code editor — VS Code

Use VS Code for editing theme and plugin files. Two features matter most:

  • Global search (Ctrl/Cmd + Shift + F) — find every place a function, hook, or plugin call appears across the whole project in a second. This is how you answer "where is this code used in the templates?"
  • The integrated terminal, when you're ready for ripgrep (rg 'function_name') or CLI Git.

5. WP-CLI — your tool for everything data

WP-CLI is WordPress from the command line. Instead of clicking around wp-admin, you run a command. It's far faster for repetitive and bulk work, and it can reach data the admin UI can't show you easily. Pair it with AI when you're not sure of the exact command — you'll pick it up fast.

The key distinction: WP-CLI is for the WordPress install (the database and what's running). It is NOT for searching code files.

  • "Where does this data exist? What ACF values are set? How many of these posts are there?" → WP-CLI (it can see the database)
  • "Where is this function called? Which template renders this field?" → VS Code search / ripgrep (that's in the files, not the database)

ACF spans both: the field keys and values are data (WP-CLI), but where those fields get output is code (editor search).

A few examples of what WP-CLI handles well:

# Plugins / maintenance
wp plugin update --all
wp cache flush                          # most caching plugins add their own, e.g. wp rocket clean

# Migrations (handles serialized data correctly — a plain DB find/replace does not)
wp search-replace 'oldurl.com' 'newurl.com'

# Backups before anything risky
wp db export

# Investigating data and ACF
wp post meta list 123                    # every meta value on post 123, incl. ACF keys
wp eval 'var_export(get_field("hero_heading", 123));'   # ACF value the proper way
wp post list --post_type=acf-field-group --fields=ID,post_title,post_name
wp post list --post_type=locations --format=count       # "how many exist"
wp db query "SELECT post_id FROM wp_postmeta WHERE meta_key='hero_heading' AND meta_value!=''"   # where data exists

6. SSH — running WP-CLI against the real site

There are two places WP-CLI runs, and the difference matters for safety:

  • Locally (a site pulled down into Local): WP-CLI runs against your local copy. Totally safe — nothing you do can touch the live site. This is your sandbox for exploring and learning.
  • Over SSH (connected to the host): WP-CLI runs against the actual live or staging data. Same commands, but now they hit production. This is the "connected to the big projects" tool you use once you're confident.

Rule of thumb:

  • Investigating, exploring, "what data exists," anything risky → do it locally on a pulled-down copy.
  • Need to read or fix something on the actual live data → SSH into the server and run WP-CLI there.

Safety note: read commands over SSH (wp post list, wp db query with a SELECT) are harmless. Write commands on live (wp search-replace, UPDATE/DELETE queries, wp plugin update) are the ones to be careful with — wp db export first, or run it locally first to confirm the result.

Most hosts we care about support this. WP Engine has SSH with WP-CLI ready to go (format environment@environment.ssh.wpengine.net, port 22). Rocket and most managed hosts do too — it's usually just grabbing the SSH credentials from the host panel.


The workflow (Phase One — no auto-deploy yet)

We are deliberately not doing automated deployment right now. Code still gets to the server manually. That's fine — the value of this phase is local development plus version control. Auto-deploy is a later step once committing is second nature.

The day-to-day loop:

  1. Pull the site down into Local (or set up a fresh local site for a new build).
  2. Pull a fresh database from staging/live if you need current content to work against.
  3. Work locally. Edit the theme/plugins in VS Code. Test against your local copy. Use local WP-CLI freely.
  4. Commit and push your code changes to the GitHub repo via GitHub Desktop. Small, frequent commits with clear messages. This is your safety net and history — even if nothing deploys, your work is saved and versioned.
  5. Deploy manually — upload the changed theme/plugin files to staging the normal way (SFTP, or the host's tool), and test there.
  6. Promote to live once staging checks out.

What you get even without auto-deploy: every change is saved and reversible, you can work offline and through host outages, two devs can work on the same site without overwriting each other, and there's a clear record of what changed and when.


Per-project setup checklist

Do this once per client, the first time you work on their site.

  • Site pulled down into Local (or fresh local site created for a new build)
  • wp --info runs in Local's shell (confirms WP-CLI is working locally)
  • GitHub repo created for the client (one repo per client)
  • .gitignore added at the site root (see sample below)
  • Repo confirms it's tracking only the custom theme + any custom plugins — not core, not uploads, not third-party plugins
  • First commit pushed to GitHub
  • SSH credentials located in the host panel (for when you need live WP-CLI) — but do exploration locally first

Sample .gitignore

Place this at the WordPress site root. Replace CLIENT with the client's slug. It ignores everything we don't write and tracks only our custom code.

# --- WordPress core (never tracked) ---
/wp-admin/
/wp-includes/
/wp-*.php
/index.php
/license.txt
/readme.html
/xmlrpc.php
wp-config.php

# --- Content & generated files (never tracked) ---
/wp-content/uploads/
/wp-content/cache/
/wp-content/upgrade/

# --- Third-party plugins & default themes ---
/wp-content/plugins/*
/wp-content/themes/twenty*/

# --- Track ONLY our custom code ---
# The custom theme is not ignored above, so it's tracked by default.
# Un-ignore our custom plugin (note the /* on the plugins line above is required for this to work):
!/wp-content/plugins/CLIENT-custom/

# --- Local / tooling noise ---
.env
node_modules/
*.log
.DS_Store

When you get stuck

You're not expected to memorise WP-CLI or Git. Lean on AI for the exact command or to interpret output — describe what you're trying to do, paste what you see, and ask. The skill to build is the workflow (local → commit → push → deploy), not command recall.

The honest framing: this isn't about becoming a different kind of developer. It's about never losing work and never being blocked by a server you don't control. Learn it locally first, where nothing can break, then it's the same tools on the real site.