Skip to content
Inte tillgänglig på svenskaEnglish
Get in touch

A feature belongs in a plugin when it should survive a theme change

Adding a feature to a WordPress or WooCommerce site means choosing between the theme, a child theme and a plugin. One question decides most cases, and a few more settle the rest.

Sooner or later every WordPress site needs something the theme cannot do. A booking step, an extra field at checkout, a different way to list products. The quick answer is to add the code wherever it works today, usually the theme. The cost shows up later, at the next redesign or the next update.

There are three places a feature can live: the theme, a child theme or a plugin. In most cases one question decides it.

The one question

Should this still work if you change the design tomorrow?

If the answer is yes, it is functionality, and it belongs in a plugin. If the answer is no, it is presentation, and it belongs in the theme.

A booking form, a sync with the warehouse, a custom shipping rule, a field the order admin needs: all of these should survive a redesign. A different layout for the product page, a new font or a changed header should not, because a new design will replace them anyway.

The WordPress theme handbook draws the same line: themes control the presentation of content, plugins control the behaviour and features of the site. The line gets blurry in practice, but the question above settles most cases quickly.

What goes wrong in the theme

Putting functionality in the theme works until one of three things happens.

The theme is updated. If the code sits in a theme from a marketplace, the next update replaces the files and the feature is gone. This is the most common way custom work disappears without anyone noticing.

The site is redesigned. The new theme does not contain the old code, so features have to be found and moved by hand. Things get missed, often the small ones that only an editor or the warehouse notices weeks later.

Someone else takes over. A developer who opens the theme expects templates and styles. Business logic buried in functions.php is easy to break without realising it was there.

When a child theme is enough

A child theme inherits everything from its parent and lets you override parts of it. Changes in the child theme survive updates to the parent.

It is the right place for design changes on top of an existing theme: styles, template overrides and small adjustments to how things are shown.

WooCommerce templates follow the same idea. Copying a template into yourtheme/woocommerce/ overrides it, as described in the template structure documentation. The catch is that WooCommerce updates its templates too. When the original changes, the copy in the theme is outdated, and the System Status report under WooCommerce > Status flags it as outdated. Every overridden template is something to check after major updates, so keep the number low.

A child theme is not the right place for functionality, for the same reason as the theme. It is still tied to the design.

When a plugin is the right call

A plugin is the right home when the feature:

  • has to keep working through a redesign or a theme change
  • stores data, such as settings, extra order fields or a log
  • talks to another system, such as an accounting program, a warehouse or a carrier
  • should be possible to switch off without touching the design
  • might be reused on another site

A plugin for a single site does not have to be big or published anywhere. Many are a single file in wp-content/plugins.

Hooks before overrides

WordPress and WooCommerce are built around hooks: places in the code where you can run your own function (actions) or change a value before it is used (filters).

Using a hook is almost always better than overriding a template or editing core files, because:

  • Updates do not overwrite it, and hooks rarely change between versions.
  • It is small. You change one thing instead of maintaining a copy of a whole file.
  • It is easy to find and remove. The behaviour lives in one function in one plugin.

If there is no hook where you need one, that is a reason to look for a different approach before overriding a template. Often there is a filter one step earlier that does the job.

Write it to fail safely

A plugin that depends on WooCommerce should check that WooCommerce is active before it runs, as described in the WooCommerce developer docs. Otherwise switching WooCommerce off, or an update that fails halfway, can take the whole site down with a fatal error.

A few more habits save trouble later:

  • Prefix everything: function names, option names and database tables. Two plugins using the same name is a common source of hard-to-find bugs.
  • Store settings in one option instead of many, and decide whether it needs to be autoloaded.
  • Clean up on uninstall. Leftover options and tables are a quiet source of slowness years later.
  • Put the version in the plugin header and in the code, so you can tell which version a site runs.

What about page builders and snippets?

Two more options often come up.

Page builders handle layout and content well, and editors like them. They are a poor place for logic. A pricing rule hidden in a builder block is as tied to the design as one in the theme, and harder to find.

Code snippet plugins let you paste PHP into the admin. They are fine for a quick test or a one-line filter. For anything that grows beyond a few lines, a real plugin file is easier to version, review and move between staging and production. Snippets stored in the database also do not show up in version control, so changes are hard to trace.

Keep it in version control

Whichever place you choose, keep the code in Git. A plugin or child theme in a repository can be reviewed, rolled back and deployed the same way to staging and production. Code edited directly on the live server cannot, and is often the first thing lost when a host is changed or a backup is restored.

A quick guide

  • Looks different, behaves the same: child theme.
  • Changes a WooCommerce page layout: template override in the child theme, kept to as few files as possible.
  • Adds or changes behaviour: plugin, using hooks.
  • Connects to another system: plugin, always.
  • Small tweak that only makes sense with this design: child theme.

The cost of getting it wrong

The choice makes no difference on the day the feature is built. It shows the day the theme is updated, the design is replaced or someone new opens the code. Functionality kept in a plugin, built on hooks, moves to a new design without anyone having to remember it was there. Functionality kept in the theme has to be rediscovered, usually after a customer reports that something stopped working.

Sources

  • WordPress
  • WooCommerce
  • plugins
  • themes
  • maintenance

Keep reading

More articles

All articles
  • 25 August 2026 · 6 min read

    Most WooCommerce slowdowns come from five places

    A slow WooCommerce store is rarely a mystery. Autoloaded options, scheduled tasks, order storage, heavy plugins and uncached pages explain most cases. How to find which one it is before changing anything.

  • 24 September 2026 · 6 min read

    Subscriptions, B2B prices and multiple currencies are where standard stores run out

    Standard store setups handle one currency, one price list and one-off purchases well. Adding subscriptions, business customers or new markets changes the checkout, payments and order admin. What changes and where the limits are.

  • 14 September 2026 · 6 min read

    Order sync breaks on retries, not on the happy path

    Connecting a store to accounting or a warehouse is easy when everything works. Webhooks, polling, idempotency and what happens when one system is down decide whether orders arrive once, twice or not at all.