Skip to main content

Installer in Joomla

18 June 2026

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.

Back to top

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.

ViewScreenJob
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:

  • InstallController handles the actual install from upload, folder, or URL.
  • ManageController handles enable, disable, and uninstall (called "remove").
  • UpdateController downloads and applies pending updates.
  • DiscoverController runs the disk scan and registers found extensions.
  • DatabaseController runs the schema "Fix".
  • UpdatesiteController and UpdatesitesController edit 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.

Back to top

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.

MethodHowWhen 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.

Back to top

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 top

5. 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.

ActionEffect
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 like com_content carry 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 top

6. 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 top

7. 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.

Back to top

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_filesize and post_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 top

9. Under the Hood (Developer View)

9.1 The Tables com_installer Touches

TableHolds
#__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:

AdapterInstalls 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.

EventFires
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, chiefly core.manage (use the screens) and core.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 tmp folder before anything is copied. If that folder is missing or not writable, the install fails early. The Warnings screen flags this.
Back to top

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.

OptionDefaultWhat 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 top

11. 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:

ParameterValuesEffect
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.

Back to top

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 top

13. 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.

Back to top

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 Warnings screen.
  • 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 Database screen.
  • Uninstall extensions you no longer use - a smaller stack is faster and safer.
  • Restrict who has core.manage and core.admin on com_installer.
Back to top

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 top

16. 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 #__extensions and 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
Installer in Joomla
Peter Martin
Peter Martin

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