Installer in Joomla
Every Joomla site grows by adding things: a backup tool, a form builder, a new template, a language pack. One core component handles all of it. It installs the file, keeps it updated, and removes it again when you are done. That component is com_installer, and you meet it every time you open the System menu.
This article explains how the Joomla Installer component really works. It covers the basics for website owners and editors, the day-to-day screens for administrators, and the technical details for developers: the views, the install pipeline, the update system, the database tables, the Options, and the REST API.
One component, six screens, and the single pipeline that installs, updates, and removes everything you add to Joomla.
The goal is simple: help you understand com_installer well enough to install, update, and troubleshoot extensions with confidence.
1. The Basics
1.1 What com_installer Is
com_installer is the core Joomla component that manages the whole life of an extension: install, enable, disable, update, and uninstall. It does not live under its own top-level menu. Instead, it surfaces as a group of screens under System in the administrator.
It is itself an extension (a component named com_installer), and it is marked protected, so you cannot remove it by accident. Without it, you could not add or update anything else.
If a screen lets you add, update, or remove an extension, you are looking at com_installer.
1.2 Where to Find It
All of the installer screens sit under the System menu, split across three groups:
System
├─ Install
│ └─ Extensions (add new)
├─ Update
│ └─ Extensions (pending extension updates)
└─ Manage
├─ Extensions (enable / disable / uninstall, see every row)
├─ Update Sites (where updates come from)
├─ Discover (register files already on disk)
├─ Database (check and fix the schema)
└─ Warnings (environment problems)
Each line is a different view of the same component. The URL gives it away: every one of these screens is index.php?option=com_installer&view=... in the administrator.
1.3 What It Is Not
com_installer handles extensions: the add-ons you bolt onto Joomla. It does not update the Joomla core itself. That is a separate component, com_joomlaupdate, reached from System → Update → Joomla. People confuse the two often, so keep the split in mind: com_installer for your add-ons, com_joomlaupdate for the CMS.
2. The Anatomy of the Component
2.1 One Component, Many Views
com_installer follows Joomla's standard Model-View-Controller (MVC) structure. Each screen you saw under System is a view with its own model and template. Knowing the view names helps when you read a URL or a bug report.
| View | Screen | Job |
|---|---|---|
install |
Install → Extensions | Upload, fetch, or point at a package and install it |
manage |
Manage → Extensions | List every installed extension; enable, disable, uninstall |
update |
Update → Extensions | List and apply pending extension updates |
updatesites |
Manage → Update Sites | List and rebuild the update URLs Joomla polls |
discover |
Manage → Discover | Find manifests on disk that have no database row |
database |
Manage → Database | Compare and fix the database schema |
warnings |
Manage → Warnings | Show environment problems detected by the installer |
languages |
Install Languages | Install language packs from the official list |
2.2 The Shared Base Model
The list views (manage, update, discover, updatesites, languages) all extend one shared model, InstallerModel. That is why they look and behave alike: the same search box, the same filters, the same pagination. Each view adds only what is special to it.
2.3 The Controllers
Every action you click maps to a controller. The names read like the buttons:
InstallControllerhandles the actual install from upload, folder, or URL.ManageControllerhandles enable, disable, and uninstall (called "remove").UpdateControllerdownloads and applies pending updates.DiscoverControllerruns the disk scan and registers found extensions.DatabaseControllerruns the schema "Fix".UpdatesiteControllerandUpdatesitesControlleredit and rebuild update sites.
You rarely touch these names directly, but they appear in the task part of a URL, for example task=update.update, and in the access checks described later.
3. Installing Extensions
3.1 The Four Ways to Install
The install view offers four tabs. They all end in the same pipeline; they differ only in how the package reaches the server.
| Method | How | When to use it |
|---|---|---|
| Upload Package File | Drag-and-drop or pick a .zip from your computer |
The normal way - you have the file |
| Install from Folder | Give a server path to an already-unzipped folder | Large packages, or files uploaded by FTP |
| Install from URL | Paste a direct link to a .zip |
The vendor gives you a download link |
| Install from Web | Browse the Joomla Extensions Directory inside Joomla | Discovering and installing in one place |
"Install from Web" is an app-store experience built into the backend. It talks to the Joomla Extensions Directory (JED) through a separate plugin, and you have to accept its terms once before it appears.
3.2 What "Install" Actually Does
Whatever method you pick, handing com_installer a package starts the same fixed sequence:
1. Unzip the package into a temporary folder
2. Find and parse the manifest → read type, files, sql, scriptfile
3. Run the script preflight() → may abort the install
4. Copy files to their homes → components/, modules/, plugins/, media/
5. Run the install SQL → CREATE TABLE #__example...
6. Register the PSR-4 namespace
7. Write the #__extensions row + manifest_cache
8. Register any update sites from the manifest
9. Run the script postflight() → seed data, show a message
10. Delete the temporary folder
If any step fails, com_installer rolls the whole thing back. You never end up with a half-installed extension on disk but missing from the database.
3.3 The Upload Size Limit
The most common install failure has nothing to do with Joomla. A large .zip can exceed PHP's upload_max_filesize or post_max_size, and the upload simply stops. When a big package will not upload, use Install from Folder (upload the unzipped files by FTP first) or Install from URL instead. The Warnings screen, covered later, reports these PHP limits so you can see them at a glance.
4. Discover: Installing Files Already on Disk
4.1 Why Discover Exists
Sometimes extension files arrive without going through the installer: an FTP upload, a Git checkout, or a folder copied from another site. The files exist on disk, but there is no row in the #__extensions table, so Joomla acts as if the extension is not there.
4.2 How It Works
Manage → Discover
→ scans the standard folders for un-registered manifests
→ lists what it finds
→ you select them and click Install
→ the missing #__extensions rows are created
Discover does no file copying. The files are already where they belong. It only creates the database rows that make Joomla aware of them. It is the bridge between "files on disk" and "an extension Joomla actually manages".
If a Discover scan finds nothing after you copied files, double-check that the manifest XML sits in the folder Joomla expects for that type, and that the folder name matches the element name.
Back to top5. The Manage Screen
5.1 Your Control Panel
System → Manage → Extensions is the main view of com_installer. It lists every row in the #__extensions table: core and third-party, enabled and disabled, every type.
| Action | Effect |
|---|---|
| Enable / Disable | Toggles the enabled column - a disabled extension does not run |
| Uninstall | Removes the files, runs the uninstall SQL, deletes the row |
| Filter | By type, by location (site or administrator), by status, by folder |
| Search | By name; sort by name, type, version, date, or author |
5.2 Protected and Locked
Two flags stop you from breaking the site by accident:
- Protected (
protected = 1) means the extension cannot be uninstalled. Core extensions likecom_contentcarry this flag. - Locked (
locked = 1) means the extension cannot be disabled or edited.
This is why the Manage screen refuses to let you remove com_installer itself, or disable the default language. The buttons are simply not offered for those rows.
5.3 Filtering Core Versus Non-Core
A fresh Joomla 6 install ships with around 150 extensions. To find your own add-ons among them, set the location and status filters, or use the "core" filter exposed in the API (described later). Most day-to-day work is on the small set of extensions you added yourself.
Back to top6. The Update System
6.1 Update Sites: How Joomla Knows an Update Exists
com_installer never guesses. Each extension can register one or more update sites: URLs that Joomla polls to ask "is there a newer version?". They live in #__update_sites, linked to extensions through #__update_sites_extensions.
#__extensions --< #__update_sites_extensions >-- #__update_sites
(com_example) (https://.../update.xml)
No update site means com_installer can never offer an update for that extension. This is the single most common reason a manually installed extension never shows an update notice.
6.2 The Update Sites Screen
Manage → Update Sites lists every registered update URL and lets you enable, disable, or delete them. It also has a Rebuild button. Rebuild re-reads every installed manifest and recreates the update site records from scratch. Use it when updates stop appearing and you suspect the update site list got out of sync.
6.3 The Update Flow
Scheduled check / page load / "Find Updates"
↓
Joomla fetches each update site's XML
↓
Compares the advertised version with the installed version
↓
Newer? → a row in #__updates → shown under Update → Extensions
↓
You click Update → Joomla downloads the package
↓
...and runs the exact same install pipeline (method="upgrade")
An update is just an install of a newer package over the top of the old one. Same manifest, same SQL step, same rollback safety. There is nothing special about "update" except that the extension already exists.
6.4 Caching the Update Check
Polling every update site on every page load would be slow, so com_installer caches the result. The Update Cache Time option (default 6 hours) controls how long Joomla trusts the last check before asking again. If you just released or installed a new version and the update does not show, use the Find Updates button to force a fresh check, or lower the cache time temporarily.
Back to top7. The Database Screen
7.1 Keeping the Schema in Sync
Manage → Database compares the SQL update files shipped inside each extension against what is actually in your database. When an update copied new files but the matching SQL never ran, the tables fall behind. This screen finds that gap.
- It lists every extension whose database structure is out of date.
- A Fix button replays the missing schema changes.
- It is the cure for the red "Database schema is out of date" warning on the home dashboard.
7.2 How It Knows: #__schemas
The check works through one small table, #__schemas, which records the highest schema version applied for each extension.
#__schemas
extension_id | version_id
27 (com_content) | 6.0.0
10000 (com_example) | 1.1.0
Each extension's update folder holds SQL files named after versions, for example sql/updates/mysql/1.1.0.sql. After running them, Joomla writes the highest applied version into #__schemas. So #__extensions.manifest_cache stores the file version, while #__schemas stores the database version. When the two disagree, that is the warning, and Fix replays the missing SQL to close the gap.
8. The Warnings Screen
8.1 What It Reports
Manage → Warnings shows environment problems the installer cares about, before they cause a failed install. Typical entries include:
- PHP settings that limit uploads, such as
upload_max_filesizeandpost_max_size. - Missing PHP extensions an install may need, such as
zip. - Folders that are not writable, so files cannot be copied.
- Leftover files from a previously failed install.
8.2 When to Look Here
Check this screen whenever an install "succeeds" but the extension misbehaves, or when an upload fails for no clear reason. The numbers it reports for PHP upload limits explain most "my package will not upload" problems in seconds.
Back to top9. Under the Hood (Developer View)
9.1 The Tables com_installer Touches
| Table | Holds |
|---|---|
#__extensions |
One row per installed extension - the registry of the site |
#__update_sites |
The update URLs Joomla polls |
#__update_sites_extensions |
Links update sites to the extensions they serve |
#__updates |
Pending updates found during the last check |
#__schemas |
The applied database-schema version per extension |
9.2 The Installer Class and Its Adapters
None of the screens contain the real install logic. They all call one framework class, Joomla\CMS\Installer\Installer, which orchestrates the whole sequence: unzip, parse the manifest, copy files, run SQL, write the row, fire events, clean up.
The clever part is that Installer does not know how any specific extension type is installed. It delegates that to a matching adapter. Each extension type has its own adapter class under Joomla\CMS\Installer\Adapter:
| Adapter | Installs the type |
|---|---|
ComponentAdapter |
component (com_) |
ModuleAdapter |
module (mod_) |
PluginAdapter |
plugin (plg_) |
TemplateAdapter |
template (tpl_) |
LanguageAdapter |
language (xx-XX) |
LibraryAdapter |
library (lib_) |
PackageAdapter |
package (pkg_) |
FileAdapter |
file |
At install time, Installer reads the type attribute from the manifest, loads the adapter with that name, and hands the work over. This is why a component, a plugin, and a language pack all go through "the installer" yet each ends up in a different place with different database changes. Adding support for a brand-new extension type would mean writing a new adapter, not changing Installer itself.
Two more classes complete the picture: InstallerAdapter is the shared base every adapter extends, and InstallerScript is the base for an extension's own preflight/postflight script (covered in the extensions article).
9.3 Installer Events: Hooking Install and Update
com_installer fires events around every install, update, and uninstall. Any enabled plugin can listen, which lets it react when another extension is installed or updated. This is how commercial vendors add a download key at update time, with no change to the core.
| Event | Fires |
|---|---|
onInstallerBeforePackageDownload |
Just before a package is downloaded - inject a key, change the URL |
onExtensionBeforeInstall / onExtensionAfterInstall |
Around installing any extension |
onExtensionBeforeUpdate / onExtensionAfterUpdate |
Around updating any extension |
onExtensionBeforeUninstall / onExtensionAfterUninstall |
Around removing any extension |
// A vendor plugin adds its subscription key to the download URL:
public function onInstallerBeforePackageDownload(&$url, &$headers)
{
if (str_contains($url, 'example.org')) {
$url .= '&key=' . $this->params->get('download_key');
}
}
9.4 Programmatic Install
You can drive the installer from your own code with the same Installer class. This is what scripts, migrations, and the CLI use under the hood; it picks the right adapter for you based on the manifest.
use Joomla\CMS\Installer\Installer;
$installer = new Installer();
// Install from an already-unzipped folder:
if ($installer->install('/path/to/unzipped/extension')) {
// success
}
9.5 The Security Boundary
Installing an extension means copying and running code on your server, so com_installer is a real security boundary. It checks several things on every install:
- Access control: it defines its own ACL actions in
access.xml, chieflycore.manage(use the screens) andcore.admin(full control). Restrict these to administrators you trust. A user who can install extensions can effectively run any code on your server. - CSRF tokens: every install, update, and uninstall request carries a one-time token, so an attacker cannot trick a logged-in admin into installing something through a forged link.
- A writable temporary directory: packages are unzipped into Joomla's
tmpfolder before anything is copied. If that folder is missing or not writable, the install fails early. TheWarningsscreen flags this.
10. Options and Configuration
10.1 Where the Options Live
Click Options on any installer screen, or open System → Manage → Extensions and use the toolbar, to reach com_installer's own settings. They are stored as JSON in the component's #__extensions row, like every other extension's Options.
| Option | Default | What it does |
|---|---|---|
Update Cache Time (cachetimeout) |
6 hours | How long Joomla trusts the last update check before polling again |
Minimum Stability (minimum_stability) |
Stable | The lowest release stability the updater will offer |
10.2 Minimum Stability
The Minimum Stability option decides which advertised versions com_installer is willing to show you. The levels, from loosest to strictest, are:
Development < Alpha < Beta < Release Candidate < Stable
Leave it on Stable for production sites, so you only ever see finished releases. Lower it only on a test site where you deliberately want to try pre-release versions of an extension. A common surprise is an update that "will not appear" because it is a beta while the setting is Stable: that is the option working as intended.
Back to top11. Web Services API
11.1 Listing Extensions Over REST
com_installer exposes its Manage list through the Joomla Web Services API. With the API enabled and a token created under your user profile, you can read the installed-extension list from outside Joomla. The route is:
GET /api/index.php/v1/extensions
curl -H "X-Joomla-Token: <token>" \
"https://example.test/api/index.php/v1/extensions"
11.2 Filtering the List
The endpoint accepts query parameters that match the screen filters, so you can narrow the result to what you care about:
| Parameter | Values | Effect |
|---|---|---|
core |
true / false |
Only core, or only non-core, extensions |
type |
component, plugin, ... |
One extension type |
status |
integer | Filter by enabled or disabled state |
curl -H "X-Joomla-Token: <token>" \
"https://example.test/api/index.php/v1/extensions?core=false&type=plugin"
This is useful for monitoring: a script can pull the list of non-core extensions across many sites and flag anything disabled, outdated, or unexpected. Note that the public API covers reading the list; installing and updating still happen through the backend screens or the CLI.
11.3 The CLI Alternative
For automation that changes things, the Joomla command-line tool can check for and apply core updates and run scheduled tasks. For extension management, the backend screens and the framework Installer class remain the main tools.
12. SEO and Metadata
com_installer is an administrator-only component. It has no front-end view, no menu item type, and produces no public pages. That means it has no direct SEO footprint: search engines never see it, and it needs no metadata, SEF settings, or sitemap entries.
Its connection to SEO is indirect but real. The extensions you install through com_installer shape your site's speed, markup, and structured data. A bloated stack of unused extensions slows pages down and hurts ranking. Keeping the installed set lean, with the Manage screen, is good housekeeping that pays off in performance.
Back to top13. Common Mistakes and Pitfalls
13.1 Confusing Extension Updates with Joomla Update
Symptom: You run System → Update → Joomla faithfully, but extensions stay outdated.
Fix: These are two components. Extension updates live under System → Update → Extensions (com_installer); the core lives under Update → Joomla (com_joomlaupdate). Check both.
13.2 A Package That Will Not Upload
Symptom: A large .zip fails or stalls on Upload Package File.
Fix: The file exceeds PHP's upload_max_filesize or post_max_size. Check the limits on the Warnings screen, then use Install from Folder or Install from URL instead.
13.3 No Update Notice Ever Appears
Symptom: A manually installed extension never offers an update.
Fix: It probably has no update site. Open Manage → Update Sites, confirm the site exists and is enabled, and use Rebuild if the list looks wrong.
13.4 The Update Seems Late
Symptom: A new version is out, but Joomla does not show it.
Fix: The update check is cached. Click Find Updates to force a fresh poll, or lower Update Cache Time in the Options. Also confirm Minimum Stability is not hiding a pre-release.
13.5 Copying Files Without Discover
Symptom: You uploaded an extension's folder by FTP, but Joomla does not see it.
Fix: Files on disk are not an installed extension until they have a #__extensions row. Run Manage → Discover to register them, or install the zip the normal way.
13.6 Ignoring the Schema Warning
Symptom: A red "Database schema is out of date" message that you keep dismissing.
Fix: It means an SQL migration did not run. Go to Manage → Database and click Fix before strange bugs appear.
14. Best Practices
If you only remember a few things from this article, remember these:
- com_installer manages your add-ons; com_joomlaupdate updates the core. Keep both current.
- Install only from the JED or directly from the developer; treat installing as running code on your server.
- When a big package will not upload, switch to Install from Folder or URL, and read the
Warningsscreen. - If updates do not appear, check Update Sites, the update cache time, and Minimum Stability in that order.
- Fix schema warnings as soon as they appear, on the
Databasescreen. - Uninstall extensions you no longer use - a smaller stack is faster and safer.
- Restrict who has
core.manageandcore.adminon com_installer.
15. Quick Reference
INSTALL System → Install → Extensions (Upload / Folder / URL / Web)
MANAGE System → Manage → Extensions (enable / disable / uninstall)
UPDATE System → Update → Extensions (pending add-on updates)
CORE UPDATE System → Update → Joomla (com_joomlaupdate, separate)
UPDATE SITES Manage → Update Sites (rebuild if updates go missing)
DISCOVER Manage → Discover (register files already on disk)
DATABASE Manage → Database (replay missing SQL with Fix)
WARNINGS Manage → Warnings (PHP limits, writable folders)
OPTIONS cachetimeout (6h) . minimum_stability (Stable)
REST GET /api/index.php/v1/extensions ?core= &type= &status=
TABLES #__extensions . #__update_sites . #__updates . #__schemas
Back to top16. Summary
com_installer is the one core component that manages the entire life of every extension you add to Joomla. It is not under its own menu; it appears as a set of screens under System.
Once you see it as a single component with several views, it all fits together:
- One pipeline: upload, folder, URL, and web all end in the same install sequence, with rollback if any step fails.
- Manage lists every row in
#__extensionsand lets you enable, disable, and uninstall. - Discover registers files already on disk; Database fixes the schema; Warnings reports environment problems.
- Update Sites and the update flow turn a remote version number into a one-click update - separate from Joomla! Update for the core.
- Options control the update cache and minimum stability; the REST API exposes the extension list at
/v1/extensions.
If you are planning a Joomla site, fighting an update that will not appear, or worried that an outdated add-on is putting your site at risk, it pays to understand how com_installer works. It is the gatekeeper for every piece of code that runs on your site, so knowing its screens is part of keeping that site fast, current, and secure.
Back to top

Joomla specialist and Linux admin for fast, secure and scalable websites.


