Skip to main content

WooCommerce extension development best practices

Following these best practices will help you create high-quality, secure, and maintainable WooCommerce extensions that work well with other plugins and provide a great experience for merchants.

Core principles

WooCommerce extensions should:

Plugin structure and naming

Main plugin file naming

The main plugin file should adopt the name of the plugin directory.

Text domain

The text domain should match your plugin directory name. Do not use underscores.

Namespacing and avoiding conflicts

Use unique prefixes

Prefix all functions, classes, constants, and global variables with a unique identifier to avoid naming conflicts.

Use namespaces for classes

Use PHP namespaces to organize your code and prevent class name collisions.

Prefix options and transients

Performance optimization

Avoid custom database tables

Whenever possible, use WordPress post types, taxonomies, and options instead of creating custom database tables.
If you must create custom tables, see the data storage primer for guidance.

Use transients for caching

Store expensive API calls or calculations in transients to improve performance.

Load scripts conditionally

Only enqueue scripts and styles where they’re needed.

Security best practices

Prevent direct file access

Add this line to the top of all PHP files to prevent direct access.
Learn more about preventing data leaks.

Validate and sanitize input

Always validate and sanitize user input.

Escape output

Always escape data when outputting to prevent XSS attacks.

Use nonces for forms

Protect forms with nonces to prevent CSRF attacks.

Internationalization (i18n)

Follow i18n guidelines

Follow the Internationalization for WordPress Developers guidelines.

Use translation functions

Wrap all user-facing strings in translation functions.

Localization files

All text strings should be in English (the WordPress default locale). If targeting a specific market, include appropriate translation files in your plugin package. Learn more at Using Makepot to translate your plugin.

Code quality and maintainability

Follow WordPress coding standards

Adhere to WordPress PHP coding standards. Key points:
  • Use tabs for indentation
  • Use Yoda conditions: if ( true === $value )
  • Use single quotes for strings unless interpolating variables
  • Always use braces for control structures
  • Follow WordPress naming conventions

Use PHPDoc comments

Document functions and classes with PHPDoc blocks.

Avoid God Objects

Break large classes and functions into smaller, focused pieces. See God Objects for more information.

Separate business and presentation logic

Keep your business logic separate from presentation code.

Remove unused code

With version control, there’s no reason to leave commented-out code. Remove it.

External libraries and dependencies

Minimize external dependencies

The use of entire external libraries is typically not recommended as this can open up the product to security vulnerabilities. If an external library is absolutely necessary:
  • Only include the strictly necessary parts
  • Use a WordPress-friendly version when available
  • Assume ownership and responsibility for the code
  • Keep libraries updated
Executing outside code within a plugin is not allowed. Using third-party CDNs for non-service-related JavaScript and CSS is prohibited.

Example: Use WordPress versions

Testing and quality assurance

Enable debugging during development

Test your code with WP_DEBUG mode enabled.
This will flag issues like undefined variables and deprecated functions.

Use the Quality Insights Toolkit

Integrate the Quality Insights Toolkit (QIT) into your development workflow. The QIT allows you to test extensions against:
  • New releases of PHP, WooCommerce, and WordPress
  • Other active extensions
  • Different configurations
Use the CLI tool to run tests against development builds.

Implement logging

Log data that can be useful for debugging, with two conditions:
  1. Make logging opt-in
  2. Use the WC_Logger class
Learn how to add a link to logged data in your extension.

WooCommerce-specific guidelines

Check if WooCommerce is active

Most WooCommerce plugins do not need to run unless WooCommerce is already active. Learn how to check if WooCommerce is active.

Never use internal WooCommerce code

Classes in the Automattic\WooCommerce\Internal namespace and code marked with @internal annotations are for WooCommerce core use only. Backwards compatibility is not guaranteed.
Internal code may change, be renamed, or be removed in any future release. Using it in your extension may cause it to break when merchants update WooCommerce. See the Internal namespace documentation for details.

Make extensions extensible

Use WordPress actions and filters to allow for modification and customization.
For more information, see Writing Extensible Plugins with Actions and Filters.

Use template files

If your plugin creates front-end output, use a templating engine so users can create custom template files in their theme’s WooCommerce folder to overwrite the plugin’s template files.

Documentation requirements

README file

All plugins need a standard WordPress README. See the WordPress plugin README file standard.

Changelog file

All plugins need a changelog file. See the changelog.txt documentation.

Plugin header

Follow the conventions in the example WordPress plugin header comment.

Summary checklist

Before releasing your extension:
  • Plugin file and directory names match
  • Text domain matches directory name (no underscores)
  • All functions, classes, and options are properly prefixed
  • Direct file access is prevented in all PHP files
  • All user input is validated and sanitized
  • All output is properly escaped
  • All strings are internationalized
  • Code follows WordPress coding standards
  • Functions and classes have PHPDoc comments
  • No unused or commented-out code
  • Scripts and styles load only where needed
  • WooCommerce active check is in place
  • No internal WooCommerce code is used
  • Tested with WP_DEBUG enabled
  • Tested with Quality Insights Toolkit
  • README.txt and changelog.txt are complete
  • Plugin header is properly formatted

Additional resources