Why Your Documentation Decides the Site’s Future
When you hand off a WordPress site, the next maintainer inherits every shortcut you took. They see the custom functions you named with three letters, the plugin you hacked instead of forking, and the settings page you hid under “Miscellaneous.” Without clear notes, that maintainer burns hours reconstructing your intent. I write this as someone who has both inherited nightmares and built sites that others later thanked me for. The difference is always documentation—written like you respect the person who comes after you, even if that person is you six months later.
Good documentation is not a novel. It is a map. It tells a competent WordPress developer where to find the important parts, what decisions you made, and how to avoid breaking things. This article lays out exactly what to capture, how to structure it, and which tools keep your notes from becoming another dead README. No theory, no filler. Just the practical items I put in every project folder.

Start with a Single README That Answers Five Questions
Every site should have a README.md in the repository root—or a DOCUMENTATION.md if you prefer. This file is the entry point. If the next maintainer reads nothing else, they should still be able to orient themselves. I structure mine to answer five questions immediately:
1. What does this site actually do?
Not just “a blog.” Write: “Marketing site for a SaaS product, with a custom post type for case studies, a member area gated by WooCommerce memberships, and a knowledge base built with a third-party plugin.” Describe the business purpose. Then, if the site uses WordPress in a non-standard way—headless frontend, multi-site network, WP-CLI scripts for data sync—state that here.
2. Where is it hosted and how do I access it?
List the host, the environment URLs (production, staging, local), and any CDN or DNS providers that matter. Include login methods: WP admin, SSH, hosting panel, database. If you use an .htpasswd or IP restriction on staging, mention it. I keep credentials out of the README itself; instead, I point to a shared password manager or an encrypted file. But the path to those credentials must be unmistakable.
3. What is the stack?
PHP version, database type and version, web server (Nginx or Apache), and any server-level customizations like custom php.ini settings or cron jobs. For a typical WordPress site, I note the theme, the parent theme if one exists, and every plugin that is not obvious. Plugins that are deactivated but kept for a reason deserve a line.
4. How do I get a local environment running?
Step-by-step commands. Even if you use a standard tool like Local or Lando, document the exact commands to pull dependencies, import a database, and build assets. If the site uses Composer for plugins or npm for theme scripts, write the sequence. Assume the next person knows WordPress but not your particular setup script.
5. What is the deployment process?
Is it Git push to deploy? Manual SFTP? A CI pipeline? Write the trigger and the steps. If there is a build step—like compiling SCSS or minifying JS—state whether that happens locally before commit or on the server. Nothing frustrates a maintainer more than pushing a fix and watching the site break because they skipped a Gulp task.

Document the Theme Like a Builder, Not a Tourist
The theme is where most custom logic lives. A maintainer needs to understand its structure without clicking through every file. I add a THEME.md file inside the theme folder that covers these sections.
Template hierarchy and custom page templates
List every template file that deviates from the standard WordPress hierarchy. For each, note which pages use it and why. Example: “page-landing.php – Used for PPC landing pages. Strips header and footer. Assigned via page meta field _wp_landing_template set by a custom plugin.” This prevents someone from deleting a template they think is unused.
Custom functions and hooks
Group functions by purpose: setup, performance, custom queries, filters. For any function that changes default WordPress behavior—like modifying the excerpt length or reordering admin columns—explain why. If you added action hooks inside templates to let plugins inject content, list those hook names and their parameters. I often paste the exact do_action() calls so a maintainer can search the codebase and instantly find injection points.
Enqueued assets and dependencies
Document every script and stylesheet the theme enqueues, especially those loaded conditionally. Note whether jQuery is a dependency or if you removed it. If you use a custom build of a library like Swiper or a specific version of Bootstrap, write it down. The next person will need to update those libraries one day, and version numbers save hours of guesswork.
Customizer settings and theme mods
If the theme uses the Customizer for logos, colors, or layout options, list the setting IDs and their default values. A maintainer debugging a missing logo should not have to trace get_theme_mod() calls through five files. A simple table with setting name, default, and where it renders is enough.
Plugins: The Land of Hidden Dependencies
WordPress sites often have plugins that depend on other plugins, plugins that are mu-plugins (must-use), and plugins that were custom-built for one job. Document each category separately.
Active plugins with non-obvious configurations
Do not list every plugin. List the ones that require explanation. For Yoast SEO, note if you changed the post type sitemap settings. For WooCommerce, note custom email templates or checkout field modifications. For a caching plugin, document the exact settings that work with your host; a maintainer who flushes cache carelessly can break a fragile setup.
Custom plugins and mu-plugins
Every custom plugin gets its own README.md or at least a header comment block that states its purpose, author, and any hooks it provides. If the plugin registers a custom post type, document the post type slug, capabilities, and any REST API modifications. I recently inherited a site where a custom plugin registered a “Team” post type with a rewrite slug that conflicted with a page. The original developer knew; I did not. A one-line note would have saved me an afternoon.
Plugin interdependencies
Create a small dependency map. For example: “WooCommerce Bookings requires WooCommerce 4.0+. The custom ‘Event Check-in’ plugin hooks into woocommerce_booking_confirmed action.” If a plugin was forked and placed in the mu-plugins folder to prevent updates, explain why the fork exists. Could be a bug fix awaiting upstream merge, could be a feature removal. The maintainer needs to know which.

Data Model and Custom Fields: Leave a Trail
WordPress sites often accumulate custom fields from ACF, Meta Box, or hand-coded add_meta_box() calls. These fields are invisible in the database until you query for them. Document them.
Custom post types and taxonomies
For each custom post type, list the slug, the capabilities, whether it is public or used only internally, and which templates display it. For taxonomies, list the slug, the object types it is registered for, and any custom rewrite rules. If a taxonomy is hierarchical, note that; it changes how you call get_terms().
Post meta and options
Create a table of important meta keys. Include the key name, the data type (string, array, integer), the screen where it is set, and the frontend location where it is used. This is tedious to write but invaluable to read. When a maintainer needs to run a WP-CLI query to update 500 posts, they will have the exact meta key at hand instead of guessing _project_client_name vs _client_name.
Transients and object cache
If your site sets transients with custom names, list them. A maintainer debugging stale data should know that homepage_featured_posts is a transient set for 12 hours, not a core option. This is especially important on sites where object caching is used aggressively.
Common Maintenance Tasks: Write the Recipes
Every site has tasks that repeat: updating content in bulk, clearing a specific cache, running a data import. Write step-by-step recipes for the top five tasks you perform. Use exact WP-CLI commands where possible. Example:
# Regenerate all attachment metadata after migrating uploads
wp media regenerate --yes --only-missing
If a task requires the admin panel, write the exact menu path: Users → All Users → [username] → Edit. Assume the maintainer has never seen this particular admin sidebar before.
Scheduled tasks and cron jobs
WordPress pseudo-cron is unreliable on low-traffic sites, so many developers set up real server cron jobs. Document every cron job, its schedule, and the command it runs. If you replaced WP-Cron with a system cron that hits wp-cron.php every 15 minutes, write that down. The maintainer who moves the site to a new server will thank you when they do not lose scheduled post publishing.
Backup and restore procedure
Even if the host provides backups, document how to manually export the database and wp-content. Include the exact mysqldump command with flags you know work for that host. A restore test is part of this documentation; note any quirks like serialized data that must be handled with a search-replace tool.
Style Guide: Design Decisions That Affect Code
A maintainer who understands the design intent makes better code changes. I add a short style guide to the documentation. It covers the design system, not just colors and fonts.
Spacing and layout rules
If the site uses a consistent vertical rhythm—say, all sections have 80px padding-top and 60px padding-bottom—state that. When a maintainer adds a new section, they will match the existing rhythm instead of eyeballing it. Note the grid system (Bootstrap 5, CSS Grid, custom flexbox) and breakpoints.
Typography tokens
List the font families, weights, and sizes for headings and body text. If the theme uses fluid typography via clamp(), provide the formula. This prevents a maintainer from adding a hard-coded 24px heading that breaks on mobile.
Color palette and usage
Provide hex codes and their roles: primary, secondary, accent, text, background, border. Note any CSS custom properties defined in the theme. If a color appears only in the Customizer, mention that so a maintainer does not override it in CSS and wonder why nothing changes.
Where Documentation Lives and How It Stays Alive
Documentation that lives in a Google Doc nobody reads is worthless. I keep documentation as close to the code as possible: Markdown files in the repository. They travel with the code, they are version-controlled, and they can be read in any text editor. For larger teams, a wiki or Notion can work, but I still keep a core README in the repo as the source of truth.
Version your documentation
At the top of the README, add a “Last updated” date and the WordPress version the site was tested on. This tells the maintainer how stale the notes might be. If you make a significant change to the site—like swapping a plugin or refactoring a template—update the documentation in the same commit. A commit message like “Replace slider plugin” without an update to the README creates drift.
Use diagrams where words fail
A data flow diagram showing how a form submission travels from frontend to database to email notification is worth a thousand words. I use Mermaid syntax inside Markdown because it renders on GitHub and many docs platforms. Even a hand-drawn photo embedded in the README is better than a paragraph that nobody will parse.
What to Do When You Inherit an Undocumented Site
You will not always be the one writing documentation from scratch. Sometimes you are the maintainer staring at a mess. In that case, document as you explore. Start a new ARCHITECTURE.md and fill it in while you trace requests. This is a topic I cover in more depth when discussing common WordPress site issues—for example, when a new site suddenly returns nothing found, the diagnostic process itself can become your documentation. What to Fix First When a New WordPress Site Says Nothing Found walks through a systematic debugging approach that doubles as a documentation exercise.
FAQ
How much documentation is too much?
Stop when you are describing standard WordPress behavior. Do not explain how to use the Block Editor or what a widget is. Assume the reader knows WordPress core. Document only what is specific to this site: custom code, configuration choices, and non-obvious dependencies. If a file already has clear inline comments, the README can simply reference it.
Should I document bugs and known issues?
Yes. A “Known Issues” section in the README is one of the most helpful things you can leave. List the bug, the conditions that trigger it, any temporary workaround, and whether a fix is planned. This prevents a maintainer from wasting hours debugging something you already understood. If an issue is tracked in a public repository, link to it.
What is the minimum documentation for a small brochure site?
For a simple site with a standard theme and few plugins, a single README with hosting info, login paths, and a list of active plugins may be enough. Add the deployment steps and any custom CSS or template changes. Even that small file cuts down handover time from hours to minutes.
How do I keep documentation in sync with code changes?
Treat documentation as part of the definition of done. Before closing a ticket or merging a pull request that changes site behavior, update the relevant Markdown file in the same branch. Reviewers should flag missing documentation just as they flag missing tests. If you work solo, add a step to your deployment checklist: “Update README if needed.”