Deprecations and Preparing for Joomla 7
|
This content was generated with the assistance of AI and should be verified against the official Joomla documentation before being relied on in production. This sub-section’s Joomla bibliography lists the reference material consulted while preparing these pages. |
Joomla removes code slowly and announces it in advance. A method that is deprecated in one release keeps working for
years, is then removed from the core in a later major version and, when possible, is kept alive for one more release
cycle inside a compatibility plugin. This page explains that policy, walks through the official per-version migration
notes from 5.4 to 7.0, lists what the 7.0 development branch already removes, describes the "Behaviour - Backward
Compatibility 7" plugin, and summarises the product strategy for 7.x. Everything about 7.0 is a plan or a work in
progress, not a released fact, and is marked as such. The example extension is the fictitious Tallpine Hiking Club
package pkg_tallpine (component com_tallpine, namespace Tallpine\Component\Tallpine).
It was written against Joomla 6.2.x on PHP 8.3+ and checked on 2026-10-30. Joomla 6.2.0 was released on 2026-10-13
and is the current version; 5.x is in its security-only period (5.4.10 was the last bugfix release) and 4.x is end of
life. The development branches 6.3-dev and 7.0-dev exist in the source repository, and the Manual already carries
draft pages for 6.3 and for 6.4 to 7.0 that state they can change at any time.
The details of the individual APIs are covered elsewhere and are linked, not repeated:
Error Handling and Legacy APIs explains setError(), the legacy
J* class aliases, CMSObject and the Filesystem and Input packages, and
Updating Joomla and Automated Core Updates explains how
to run the update itself. The release schedule is on
Versions, Release Cycle and Support.
The deprecation policy
Joomla follows semantic versioning as far as the life cycle of a CMS allows. The Manual’s section About Updates & Upgrades Documentation states the rules that matter for extension authors:
-
a deprecation is introduced in a minor release, not in a major one;
-
deprecated code has to remain available for as long as the Joomla version in which it was deprecated is still supported, so something deprecated in 4.x can be removed at the earliest in 6.0, and it does not have to be removed then (the Production Department motion PROD2022/011 set this rule);
-
removing code earlier than that needs a separate Production Department motion;
-
wherever possible, removed code is moved into a backward compatibility plugin, so that it can be used for one more release cycle.
The practical effect is that a third-party developer has at least two years between the first deprecation notice and
the removal. The @deprecated tag in the source states both numbers, for example @deprecated 4.0 will be removed in
7.0 on CMSObject: the first number is the version that deprecated it, the second the version that is expected to
remove it. The expected removal version can move. The Manual’s 5.3 to 5.4 notes list three cases where the removal was
postponed from 6.0 to 7.0: the old event API (events without an event class), the old Editor and Captcha plugin APIs,
and JLoader::register(). Always read the migration notes of the version you target instead of relying on an older
tutorial.
The same policy explains the shape of the backward compatibility plugins:
| Major | Compatibility plugin | Role |
|---|---|---|
5.0 |
Behaviour - Backward Compatibility |
Keeps Joomla 4 code running on 5. It has to be disabled before updating from 5.4 to 6. |
6.0 |
Behaviour - Backward Compatibility 6 (BC6) |
Installed and enabled in 5.4 (where it does nothing) so that the update to 6 can run old extensions. Installed but disabled on new 6.0 installations. |
7.0 (development) |
Behaviour - Backward Compatibility 7 |
Holds the code removed in 7.0 that can still be offered for one more cycle. Not released yet. |
Both plugins belong to the behaviour plugin group because that group loads before every other plugin, which backward
compatibility needs. The Manual warns developers not to create their own plugin in the behaviour group, because the
group may be removed in a future release. The 5.4 to 6 procedure (disable the old plugin, enable BC6, switch the update
channel) is in
Upgrading Joomla 5 to 6.
A timeline from 5.4 to 7.0
The cycle is a major every two years, with four minors in between, and the last minor (x.4) is a bridge release without new features that is released together with the next major: 5.4.0 and 6.0.0 were both published on 2025-10-14. The roadmap page of the developer site lists dates only up to 6.3, and all its dates are tentative, so the dates for 6.4 and 7.0 follow from the cycle and are not announced.
The per-version migration notes
The Manual keeps the code-level notes separate from the version-specific development manual, because they are meant to be read across versions. Each pair of releases has a page with the same sub-pages: New features, New deprecations, Removed and Backward Incompatibility, and, where relevant, Compatibility Plugin. The advice is to read every page from the version your code was written for up to the version you want to support, because that also catches changes that older code never picked up.
| Step | What the notes cover |
|---|---|
5.4 to 6.0 |
The large one. New deprecations (the |
6.0 to 6.1 |
New features: the string |
6.1 to 6.2 |
New features: the modular build script system, which compiles or watches a single extension without a full rebuild. The page lists no new deprecations. |
6.2 to 6.3 |
Draft page for the development branch. No new deprecations listed so far. |
6.4 to 7.0 |
Draft pages for the development branch. They list the removals described in the next section, one new deprecation (finder plugin adapters must receive the database in their constructor) and the 7.0 compatibility plugin. |
Two cautions apply to the notes themselves. First, the pages of the minor releases say that no deprecations were
introduced "yet"; that text is written while a release is in development and is not always updated afterwards, so
check the @deprecated tags of the source (or run a static analysis, see below) instead of treating an empty page as a
guarantee. Second, the draft pages for versions that are not released can change at any time.
What 7.0 is expected to remove
The 6.4 to 7.0 page of the Manual, Removed and Backward Incompatibility, is the working list of the 7.0 development branch. It starts with a section on what moves into the compatibility plugin and then lists plain removals. The items that most affect extension code are summarised here. The list is still growing, so treat it as a preview.
Plugin properties $app and $db
Since the 4.x series, CMSPlugin filled the properties $app and $db of a plugin automatically when the class
declared them. In 7.0 that detection is removed (it is the reason older plugins "just work" without any wiring). The
same properties are removed from ActionLogPlugin ($app and $db), FieldsPlugin ($app) and PrivacyPlugin
($db). Finder plugins that extend the indexer Adapter class must now receive the database in their constructor.
A plugin that still reads $this->app or $this->db fails with a notice or an error on a null property in 7.0 unless
the compatibility plugin or its own code fills them in. The fix is to inject the services in services/provider.php,
which is also how every core plugin is written today:
<?php
\defined('_JEXEC') or die;
use Joomla\CMS\Extension\PluginInterface;
use Joomla\CMS\Factory;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\Database\DatabaseInterface;
use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;
use Tallpine\Plugin\Content\TallpineConditions\Extension\TallpineConditions;
return new class () implements ServiceProviderInterface {
public function register(Container $container): void
{
$container->set(
PluginInterface::class,
function (Container $container) {
$plugin = new TallpineConditions(
(array) PluginHelper::getPlugin('content', 'tallpine_conditions')
);
$plugin->setApplication(Factory::getApplication());
$plugin->setDatabase($container->get(DatabaseInterface::class));
return $plugin;
}
);
}
};
The extension class then uses the accessors and the aware trait instead of the properties:
<?php
namespace Tallpine\Plugin\Content\TallpineConditions\Extension;
\defined('_JEXEC') or die;
use Joomla\CMS\Event\Content\ContentPrepareEvent;
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\Database\DatabaseAwareTrait;
use Joomla\Event\SubscriberInterface;
final class TallpineConditions extends CMSPlugin implements SubscriberInterface
{
use DatabaseAwareTrait;
public static function getSubscribedEvents(): array
{
return ['onContentPrepare' => 'onContentPrepare'];
}
public function onContentPrepare(ContentPrepareEvent $event): void
{
// Joomla 5 and 6 code often used $this->app and $this->db here.
$app = $this->getApplication();
$db = $this->getDatabase();
if (!$app->isClient('site')) {
return;
}
$query = $db->createQuery()
->select($db->quoteName('closed'))
->from($db->quoteName('#__tallpine_trails'))
->where($db->quoteName('id') . ' = :id')
->bind(':id', $id, \Joomla\Database\ParameterType::INTEGER);
// ... execute and decorate the article text
}
}
Source: Joomla Manual: How plugins work
If an extension cannot use the aware trait or the provider, the Manual’s fallback is to set the properties in the
plugin’s own constructor from Factory::getApplication() and from the container entry for DatabaseInterface.
Because getApplication() and getDatabase() exist already in 5.x and 6.x, the migration can be done now, without
waiting for 7.0, and the same code runs on 5.4, 6.2 and 7.0. Core plugin classes are final, so third-party code
extends the abstract plugin base classes and not the core plugins.
CMSObject and the legacy property methods
Joomla\CMS\Object\CMSObject (formerly JObject) is annotated as deprecated since 4.0 and as removed in 7.0, with
stdClass or Joomla\Registry\Registry as the replacement. In 6.0 core stopped using it: AdminModel::getItem()
returns a stdClass, so the get() and set() methods are no longer available on the result.
The 7.0 branch goes one step further and removes LegacyPropertyManagementTrait (the get(), set(), def(),
getProperties() and setProperties() methods, which could read and write protected properties) from CategoryNode,
Changelog, BaseModel, AbstractView, Table and User. The trait has been deprecated since 4.3. Note in
particular that a model or view that called $this->set('option', ...) or $view->get('property') as a property
access now has to use ordinary public properties, while the view’s get('Items') that calls getItems() on the
model keeps working. The error-handling half of CMSObject, LegacyErrorHandlingTrait, is discussed below.
<?php
use Joomla\Utilities\ArrayHelper;
// Before (works on 5.4 and 6.x, removed on the 7.0 branch)
$title = $table->get('title');
$table->set('title', 'Lake Aurora loop');
$all = $table->getProperties(1);
$name = $user->get('name');
// After (works everywhere)
$title = $table->title;
$table->title = 'Lake Aurora loop';
$all = ArrayHelper::fromObject($table, false);
$name = $user->name;
The filesystem shim
In 6.0 the CMS classes Joomla\CMS\Filesystem\File, Folder, Path, Stream and Patcher were moved out of the
core library into BC6, with 7.0 as the announced removal. The replacement is the Joomla Framework package
joomla/filesystem (namespace Joomla\Filesystem), which is already bundled with the core. On the 7.0 branch the
compatibility plugin directory plugins/behaviour/compat7/classes/Filesystem holds the same classes again, so the
shim survives one more cycle for extensions that still call them but is not part of the 7.0 core.
<?php
use Joomla\Filesystem\File;
use Joomla\Filesystem\Folder;
use Joomla\Filesystem\Path;
// Tallpine GPX upload handler
$target = Path::clean(JPATH_ROOT . '/images/trails/' . File::makeSafe($name));
Folder::create(\dirname($target));
File::upload($tmpPath, $target);
The framework classes throw exceptions on failure instead of returning false with a warning, so a straight
search-and-replace of the namespace is not enough: wrap the calls in try/catch where a failure is expected. The
detailed comparison is in the Filesystem section of
Error Handling and Legacy APIs.
Error handling: setError() in core
The error protocol is removed in stages: setUseExceptions() and shouldUseExceptions() arrived in 5.4, core is
converted step by step during 6.x, 7.0 removes the calls to setError() and the checks of the exceptions flag from
the core, and the LegacyErrorHandlingTrait itself is planned to go in 8.0. In the 7.0 source the trait and its
methods carry @deprecated ... will be removed in 7.0 tags, and CMSObject, which uses the trait, is on the same
schedule. What matters for com_tallpine is that it stops relying on a false return value plus getError() and
calls setUseExceptions(true) on its models and tables. The full guidance, with examples, is on
Error Handling and Legacy APIs and is not repeated here.
Other removals worth scanning for
The same page lists many smaller items. The ones extension code is most likely to hit:
| Removed in the 7.0 branch | Use instead |
|---|---|
|
|
Static |
Boot the module and call the instance helper:
|
The CMS Crypt package ( |
The framework package |
|
|
Legacy one-time-password code in |
Multi-factor authentication, which replaced it in 4.2 |
The |
Users who have not logged in since Joomla 3.2.1 must reset their password |
The form fields |
|
JavaScript |
|
The generic |
The typed table events |
The Behaviour - Backward Compatibility 7 plugin
The 6.4 to 7.0 page of the Manual says that, in 7.0, the compatibility plugin of 6.0 is replaced by a new plugin called
"Behaviour - Backward Compatibility 7". The development branch already contains it as
plugins/behaviour/compat7 (extension name plg_behaviour_compat7, namespace Joomla\Plugin\Behaviour\Compat7, version
7.0.0). Its description says that, when enabled, it provides backward compatibility to the previous major version,
Joomla 6, for extensions that do not follow the current coding standards. Because it is unreleased, its options and
contents can change before 7.0.
What the branch shows today:
-
three yes/no options: Classes Aliases (aliases for renamed or namespaced classes, default off), Include Deprecated Classes (classes removed from the core but kept under the plugin’s
classesfolder, default on) and Removed Assets (empty placeholder entries in aremoved.asset.json, so that a Web Asset Manager call for a removed asset does not raise an exception, default on); -
the plugin directory contains the Filesystem classes, the CMS
Inputclasses, the CMSBaseApplication,CliApplicationand CLI helper classes, the CMS Crypt classes, theRadiobasicFieldform field and its layout; -
the plugin defines the constant
COMPAT_JOOMLA_7when it is loaded. Selected functions (Factory::getConfig(),Factory::getSession(),Factory::getMailer(),User::get()) test for that constant and throw an exception when it is missing. That makes the missing plugin visible during testing instead of silently failing in production, and it lets a site owner see which old override or extension needs attention.
The consequence for a site is the same as with BC6: enabling the plugin buys one release cycle, not a permanent solution. An extension that needs it should be treated as an extension that needs maintenance.
Preparing pkg_tallpine for Joomla 7 today
Everything below works on Joomla 5.4 and 6.2, so the package can be prepared long before 7.0 appears:
-
Update the development site to the latest 6.2.x and, if the package supports 5.4, keep a 5.4 test site as well.
-
Switch off every compatibility plugin on a test site (BC6 on 6.x) and run the package through its tests. Whatever breaks relies on removed or compat-only code. Compare with the checklist in Error Handling and Legacy APIs.
-
Search the code for the patterns above and fix them. The script below is a starting point; a result is a candidate, not a proof.
-
Raise the minimum PHP version in the package manifest only when the target Joomla version requires it. Minimum requirements rise only in the first release of a major.
-
Re-run the checks against the 7.0 development builds when they become available, and read the 6.4 to 7.0 notes again at that time, because the list will have changed.
#!/usr/bin/env bash
# Scan the Tallpine package for APIs that the 7.0 branch removes or moves to compat7.
set -eu
SRC="${1:-./pkg_tallpine}"
grep -rnE '\$this->(app|db)\b' "$SRC" --include='*.php' \
&& echo "-> use getApplication() / getDatabase() and inject in provider.php"
grep -rnE 'CMSObject|->setError\(|->getError\(|->getProperties\(' "$SRC" --include='*.php' \
&& echo "-> use exceptions and stdClass / ArrayHelper::fromObject()"
grep -rnE 'Joomla\\CMS\\(Filesystem|Input|Crypt)\\' "$SRC" --include='*.php' \
&& echo "-> use the joomla-framework packages"
grep -rnE 'Factory::get(Config|Session|Mailer)\(' "$SRC" --include='*.php' \
&& echo "-> use the application and the service container"
grep -rnE 'Joomla\.(JText|popupWindow)|window\.Calendar' "$SRC" --include='*.js' \
&& echo "-> use Joomla.Text, window.open and JoomlaCalendar"
true
Static analysis helps with the same job. PHPStan, with the Joomla stubs or the checked-out core on the autoload path, reports calls to methods that no longer exist, and the PHP deprecation tags of Joomla’s own classes are visible to IDEs. See Coding Standards and Static Analysis for the toolchain used across this sub-section, and Build and CI for Extensions for running the checks against several Joomla versions in a matrix.
Common errors and pitfalls
-
Enabling both compatibility plugins. BC and BC6 cannot be on together when updating from 5.4 to 6. After the update only BC6 is relevant. See Upgrading Joomla 5 to 6.
-
Shipping your own plugin in the
behaviourgroup. The Manual says the group may be removed. Usesystemor the group that matches the event. -
Trusting the pre-update check. The extension compatibility check is not a reliable source of truth; test on a copy.
-
Assuming a deprecated method is safe because it still works. Deprecated code is supported only until its removal version, and the removal version can be later than first announced, but it never moves earlier without a motion.
-
Relying on the compat plugin to ship. A site that needs a compatibility plugin to run is on borrowed time: the plugin lasts one major cycle.
-
Mixing protocols. Calling
setError()in a new class and checking exceptions in the caller leaves failures unreported. -
Documentation of the draft pages. The 6.3 and 6.4 to 7.0 pages are drafts; a link to them in a user guide can become stale.
Security notes
Deprecations are often security-motivated. The 7.0 branch removes the legacy password hash handler PHPassHandler
(accounts that have not logged in since Joomla 3.2.1 will need a password reset) and the obsolete one-time-password code
paths that had not worked since multi-factor authentication replaced them in 4.2. The CMS Crypt package gives way to
the maintained framework package, and the URL form-field layout no longer escapes values itself, so an extension that
renders joomla.form.field.url directly must escape the value. Staying on an unsupported release is the larger risk:
security fixes for 5.x end on 2027-10-12, and the compatibility plugins cannot be used as a long-term security
posture. Keep security patches current through
automated core updates and plan the 7.0 move early.
The strategy for 7.x, stated as plans
The Joomla Product Strategy page of the developer site was created on 2025-09-08 from a three-day sprint (it is version 1.0.3, last modified on 2025-10-01, with a roadmap status of 2025-10-05) and says that all dates are tentative. It is built on three pillars: defend and expand the market position, increase efficiency (including readiness for AI), and simplify onboarding. It splits the work into a 6.x branch (2025 to 2027) and a "7.x and beyond" branch (2027 onwards).
| Pillar | 6.x (2025 to 2027) | 7.x and beyond (2027+) |
|---|---|---|
Defend and expand |
WCAG 2.2 AA for the front end and the administrator; extended content versioning with draft states; a built-in proof-of-work captcha |
A multi-site or sub-site concept; automated workflows; filtering items by custom field values; a framework-agnostic design system for templates; a rate limiting framework |
Increase efficiency |
Documentation for end users, developers and machine-readable web services; improved web services (refined endpoints, OAuth, a "headless only" mode); MCP servers; investigation of an AI framework |
An "Ajaxified" administrator; a site-wide content language filter; a standardised horizontal component API for third-party developers; better default code for third-party developers |
Simplify onboarding |
A new sample data set; editor improvements for links and media; configurable authoring forms; intelligent module assignment; redirects for renamed, removed or unpublished items |
A new default template with the goal of one new template per major version; user interface presets for user roles |
Three of the 7.x themes matter for the Tallpine site:
-
Multisite. Joomla has no multisite support in core today; sites that need several sites use separate installations or third-party tools (see Multi-site Options and Scaling). The strategy lists a multi/subsite concept as a goal for 7.x. No design, version or date is published, so do not build a Tallpine regional-club network around it.
-
Design system. The framework-agnostic templates and design system, together with the goal of a new default template per major version, suggests that Cassiopeia may be replaced as the default in a future major. Child templates such as
cassiopeia_tallpineshould therefore keep their overrides small and their tokens (colours, fonts) in variables; see Child Templates. -
Rate limiting. A rate limiting framework is listed under defend and expand for 7.x. Until it exists, throttling of the login form, the Web Services API and the contact form belongs on the reverse proxy or web application firewall; see Web Server, Reverse Proxy and HTTPS.
For the 6.x items that touch headless use and artificial intelligence, the plans are discussed in Headless Joomla and AI, MCP and the Roadmap. All of this is a strategy, not a commitment, and the roadmap shows only what has been accepted for each release.
Where older books and tutorials are outdated
-
Developing Extensions for Joomla! 5 (2023) shows plugins that read
$this->dband$this->appas if they were permanent features, and models that returnCMSObjectinstances. Both are removed or on the way out; use the Aware traits,getApplication()andgetDatabase(), andstdClass. -
Joomla! 4 Masterclass (2023) targets 4.x, which reached end of life in 2025-10, and does not cover the compatibility plugins or the 6.x migration notes at all.
-
Tutorials that say deprecated code is removed in the next major version describe the policy before the 2022 motion. Today the earliest removal is the second major after the deprecation.
-
Material that says the
JPATH_PLATFORMguard,JFactoryandJTextare the normal way to write Joomla code predates the 6.0 removals. Usedefined('_JEXEC') or die;, namespaced classes andText.