Custom XenForo add-ons built to survive upgrades
The difference between a modification and an add-on is not how it behaves on the day it is installed. It is what happens eighteen months later when the platform moves a version and somebody has to work out what your functionality depended on.
A modification that patches the platform is a cost deferred, not avoided
It is faster to change the platform's own template than to build an extension around it. That decision is locally rational and it is why forums end up with functionality that cannot be upgraded. The work is not finished when the feature appears — it is finished when the feature exists in a form the next platform release can survive.
- A feature works, but nobody knows where in the codebase it lives
- Platform files were edited directly and are now diverged from the release
- An upgrade previously removed a piece of custom functionality
- The same functionality had to be rebuilt after a previous version change
- A modification is no longer maintained by whoever originally published it
- Requirements have grown past what a general-purpose existing add-on does
- Two add-ons conflict and the conflict is resolved by patching one of them
- Nobody can enable or disable the functionality without a deployment
The people who usually bring us this problem
A community owner with a specific requirement
What you need is close to an existing add-on but not close enough, and you need it built rather than configured.
A platform owner who has been burned by a previous upgrade
You lost functionality once already and you would rather pay for something that survives than for something that is quick.
An operator with several forums
You need one implementation deployed consistently across installations without diverging each of them by hand.
What this costs while it goes unfixed
Engineering faults are rarely confined to the engineering layer. These are the commercial consequences we see most often.
A patched platform cannot be upgraded safely
Once the platform's own files have been edited, the upgrade path requires diffing against the release, reapplying the change and validating it each time. The cost recurs on every version step, indefinitely.
Invisible dependencies make features unremovable
When customisation is tangled into the core, nobody can safely remove it later. Functionality nobody wants anymore stays, because turning it off is indistinguishable from breaking something else.
An unmaintained dependency becomes your risk
A third-party modification that stops receiving updates is a known problem with no fix except replacing it — and the longer it is left, the more functionality is built on top of it.
Capabilities
Each of these is work we carry out, not an area we advise on.
Extension-point development
Building through the platform's own extension mechanisms rather than around them, so the add-on attaches at a defined point and the underlying release stays unmodified and upgradeable.
Own data structures
Schema created and owned by the add-on itself, with install, upgrade and uninstall handled explicitly, so the add-on does not depend on internals that a future release may restructure.
Permissions and visibility
Extending the platform's own permission model rather than implementing a parallel one, so the feature respects group, node and user permissions the way every other part of the platform does.
Templates and front-end
Add-on templates as separate units, presented through the platform's templating system, so the front-end follows the installed theme rather than hardcoding a look that breaks on a redesign.
Integration with surrounding systems
Connecting the add-on to external services where needed, with the failure behaviour of each dependency considered rather than assumed.
Clean install and removal
Install, upgrade and uninstall paths that actually work, because an add-on that cannot be removed cleanly is a permanent commitment made on the owner's behalf.
Documentation and maintenance position
A written record of what the add-on does, which extension points it uses and what an upgrade would affect — and an honest statement about who maintains it and for how long.
Engineering methodology
The sequence is deliberate. The order is usually what determines whether the work holds or has to be repeated.
Establish whether an existing add-on will do
The cheapest correct answer is frequently an existing add-on, sometimes with a small piece of custom work beside it rather than a replacement for it. We check that before proposing to build anything, because building something that already exists is expensive for you and uninteresting for us.
Define the requirement around behaviour, not implementation
What the community needs to be able to do, and what has to remain true afterwards. Written that way, the requirement stays valid across platform versions; written around a specific internal mechanism, it expires.
Respect the platform's own boundaries
Extension points, the permission model, the templating system and the add-on data lifecycle are used as designed. Working with them is what makes the result upgradeable, and it is not a stylistic preference — it is the mechanism by which the add-on survives.
Own the data explicitly
Anything the add-on stores is created, migrated and removed by the add-on itself, with upgrade steps handled as the schema changes. Ambiguity here is what produces an add-on that cannot be uninstalled.
Test against a replica of the real installation
Add-ons interact with installed extensions, permission configuration and template customisations that a clean install does not have. Validation happens against a copy of the actual platform.
State the maintenance position plainly
Who maintains the add-on, what that covers, and what happens when the platform moves. An add-on with no stated maintenance position is one that quietly becomes unmaintained.
What an engagement produces
Documentation is a deliverable, not an afterthought. On most of these engagements a large part of the value is a defect report precise enough for another team to act on.
Before building
- Confirmation of whether an existing add-on would meet the requirement
- Written behaviour specification, independent of implementation
- Statement of which extension points the add-on will use
- Data the add-on will own, and its lifecycle
- Explicit scope and exclusions
The add-on
- Extension-based implementation with the platform left unmodified
- Own schema with install, upgrade and uninstall handled
- Permission integration through the platform's own model
- Add-on templates that follow the installed theme
- Tested against a replica of the production installation
After delivery
- Written documentation of behaviour and extension points
- Deployment and rollback procedure
- Stated maintenance position and coverage
- Handover to whoever operates the forum day to day
Architecture and technology
The extension model
- Code hooks at defined extension points rather than file edits
- Template modifications expressed as changes rather than replaced files
- Add-on-owned schema with an explicit upgrade path
- Integration with the platform's permission and phrase systems
- Install and uninstall that leave no residue
What upgrade-safety actually requires
- No edits to platform files
- No reliance on internal implementation details
- No assumption that a specific template will still exist unchanged
- A stated position on who tracks platform releases
- A rollback that does not depend on restoring a backup
If this is not quite your problem
These overlap at the edges. Sending you to the right page is more useful than having you work it out.
The whole platform needs work, not one feature
Add-on development is one part of platform engineering rather than a substitute for it.
XenForo developmentYou are moving onto XenForo and need an importer rather than an add-on
A bespoke importer for a non-standard source is a different problem from extending the platform.
Invision to XenForo migrationThe requirement is performance rather than functionality
Serving-path and query work belongs with the infrastructure rather than the extension.
Managed XenForo hostingFrequently asked
Should we build a custom add-on or buy an existing one?
Buy or adopt first, almost always. A maintained add-on that covers most of your requirement is cheaper, better tested against the wider ecosystem and somebody else's problem to keep current. Building custom code is the right answer when the requirement is genuinely specific to you or when the existing option has stopped being maintained — and we will tell you which of those applies rather than assuming the more interesting answer.
Will the add-on keep working when we upgrade the platform?
Built against the platform's extension points, an add-on is designed to survive version changes and normally does. It is not a guarantee, and anyone offering one is overstating what is knowable about future releases. What we commit to is that the add-on does not patch platform files, does not depend on internal implementation details, and comes with documentation of what it touches — which is what makes an unexpected incompatibility a small fix rather than a rebuild.
Do you provide ongoing maintenance for the add-on?
Only if it is agreed as part of the engagement, and we will not promise perpetual updates or lifetime support. What we will do is state the position plainly at delivery: what is covered, for how long, and what it would take to extend it. An add-on with an unclear maintenance position is one that quietly stops being maintained, and that outcome is worse than a clearly stated end date.
Can the add-on be removed cleanly?
Yes, and uninstall is treated as a first-class path rather than an afterthought. Anything the add-on creates, it also knows how to remove. An add-on that cannot be uninstalled converts a temporary feature into a permanent commitment, and that decision should not be made on your behalf by whoever wrote the code.
Do you need access to our platform to build it?
For development and validation, yes — normally a staging copy or a replica, not the live installation. Access is granted by you, on terms you set, and revoked when the work ends. For an initial conversation about scope, nothing beyond a description of the requirement and the platform version is needed.
Related capabilities and work
Bring us the problem you have not been able to fix
Describe what is happening rather than what you think the cause is. If we are not the right people for it, we will say so.