Extensions
Extensions in two clicks
- 11 extensions
- Catalog
- Manifest V3 only
- Standard
- up to 50 enabled
- Per profile
- ARMANOS Browser 153.0.7978.0
- Where they really work
The catalog is eleven cards, and every one of them installs
Open Extensions, choose a profile in the toolbar, and you get eleven cards. Each card shows a name, a version, a category and the exact folder name the app expects on disk.
The list ships inside the app, in the package the desktop and the server share. It used to live only in the server seed, so an install with no account had a dead screen. A list of well known extensions is not your data, and it no longer waits for a login.
Every entry carries a store id. That id, not the link to the publisher site, is what the Install button uses. The official mark sits only on cards published by the extension's own author.
| Category | Cards | What people use them for |
|---|---|---|
| Privacy | uBlock Origin Lite, Privacy Badger | Cutting ads and trackers inside one profile |
| Productivity | Dark Reader, Session Buddy | Night reading, saving and restoring sets of tabs |
| Wallets | MetaMask, Phantom | Web3 work in a profile of its own |
| Proxy | FoxyProxy | Per URL routing on top of the profile's own proxy |
| Developer | React Developer Tools, JSON Formatter | Debugging pages and reading API answers |
| Scraping | Web Scraper, Instant Data Scraper | Point and click collection into CSV |

Install downloads the file, checks who signed it, then unpacks it
The Install button does the whole job. It takes the store id from the catalog, asks the store for the archive, and stops the download at 80 MB.
Then it checks what arrived. The extension id is recomputed from the public key inside the file and has to equal the one you asked for. Measured once without that check: a completely different extension arrived, with different permissions, under a familiar name.
Only after that does anything move into place. Files are unpacked into a temporary folder next to the target, and the folder already there is set aside instead of deleted, so a failed install cannot take away a working extension.
- 1
The id comes from the catalog
A card's source link points at GitHub or the vendor site. Parsing that as a store link refused every single card, so the catalog's own store id wins over anything the caller sends.
- 2
Download, capped
The request goes to the store update service with the major version of the engine you actually run. The archive stops at 80 MB, so an endless answer cannot fill the disk.
- 3
Signature first, name second
A missing signature, a bad signature or a mismatched id all stop the install and say which id arrived. The manifest name is compared with the catalog name as well, skipping the translated __MSG_ form.
- 4
Manifest V3 or nothing
The manifest is read in the temporary folder. If manifest_version is not 3, the folder is deleted and the install stops with a plain reason instead of a green result.
- 5
The store id is kept
The author key from the archive is written into the manifest. Without it MetaMask came up as fjlgnkabmikfmdefngdomnbhfamofmje instead of nkbihfbeogaeaoehlefnkodbefgpgknn, and wallet dialogs that look for the known id can simply miss it.
- 6
The swap is reversible
The old folder is renamed aside, the new one moves in, and only then is the old copy removed. If the move fails, the old folder comes back.
Enable installs the files first, then records your choice
Enabling used to be the second step of a dance only its author knew. You pressed Enable, got Files missing, and decided the extension was broken, while the Install button next to it said nothing about that.
Now one button does both. If the extension has a store id and its files are not on this computer, Enable downloads and unpacks them, then switches it on for the selected profile.
The card never lets a green Enabled mean nothing at all. Next to it sits a second badge about the files themselves.
Files found
The folder is in place and its manifest is third generation, so this extension loads when the profile starts.
Files missing
There is no such folder inside the extensions directory, so nothing would load. For a catalog card, Enable fixes this itself.
Files outdated
The folder is there and the manifest is the old standard. The launch would refuse it, so this is a third state and deliberately not a green one.
The counter, before you hit it
The toolbar shows how many extensions this profile has on and the ceiling of 50, instead of letting you learn the limit from a refusal.
The choice belongs to the profile, not to the machine
Switching an extension on is remembered for that profile, by folder name, in a file written with owner only permissions. The folder name is the only identifier that means anything without a server, because it is what names the files on disk.
When you are signed in, the change also goes to your account, and the screen asks the account before it draws. So an extension you turned on at work is on at home, on the same profile.
If that send fails, you see the failure instead of a green Done. A quiet success there would be a lie, because on the second machine the choice would simply not exist.
Copying a profile copies the list of enabled extensions, and so does moving a profile to another computer. The files stay local: each machine keeps its own copy, and a deleted profile is dropped from the file.
An empty answer never means switch everything off
Only third generation extensions are accepted
Manifest V3 is the only standard that loads, at install and again at launch. Chromium 153 does not run the older one at all.
Silence would be worse than the refusal. Measured with a Manifest V2 folder handed to the engine: the browser started, the profile was marked running, the success notification arrived, and not a single page ever loaded. Automation on that profile died with it.
So such a folder is skipped before launch, and a notification names the folder, the profile and the reason. On the card you see Files outdated rather than a green badge, and the advice is to look for a Manifest V3 version.
The catalog obeys the same rule. Its first card used to be a blocker whose store copy is Manifest V2, so it could never be installed, and it promised the most from the most visible place. It was replaced by the Lite build of the same author, which is V3. A stand downloads every card from the store for real and unpacks it with the app's own unpacker.
At launch the folders reach whichever engine actually starts
A folder name arrives from two places: your local choice and your account. It then becomes part of a path, which is exactly where this kind of thing goes wrong.
Two checks stand in the way. The name has to look like a name, and the resolved path has to land inside the extensions folder. A value like ../../.. used to load any folder on the disk that happened to hold a manifest.
On the built-in engine the folders go into the profile session with file access turned off. An extension with file access could read the other profiles' cookie and login databases, which is the one boundary profiles exist to keep.
On ARMANOS Browser the same folders are passed as a load list, together with a matching disable-except list. Only what you enabled loads, and anything that found its way into the profile directory by another road does not join it.
Turning one off takes effect now
A session lives as long as the app, so an extension loaded once used to keep running after you switched it off, until you restarted ARMANOS. It is now removed from the session.
A network blip unloads nothing
If the account list could not be fetched, the answer is at least these rather than exactly these, so nothing is removed on the strength of it.
Up to 50 per profile
Beyond that the switch refuses and says why, instead of accepting the choice and quietly ignoring it at launch.
On the built-in engine a store extension does not do what its card promises
ARMANOS carries a fallback engine: ordinary Electron, used when ARMANOS Browser is not installed or cannot start. Extensions load there, and then very little happens.
This was measured on both engines with the same blocking rule, and separately with a real Dark Reader from the store. The result is the readout below, and it is the reason the Extensions screen carries a warning.
The warning appears whenever the built-in engine is what will actually start. That includes ARMANOS Browser being selected but not installed, and the app failing to ask at all. It is written in all 22 languages, and a stand executes the rule rather than searching the source for the right words.
Blocking is the one part we can carry ourselves, and we do. On the built-in engine the app reads the extension's own rule files and applies them by intercepting requests. Rules it cannot execute are counted and printed, because a working blocker must never mean half the rules were quietly dropped.
- Built-in engine, Chromium 130
- the block rule did not fire, the request reached the server
- ARMANOS Browser 153.0.7978.0
- the same request was blocked
- Dark Reader on the built-in engine
- zero styles inserted, the page did not change
If the built-in engine ever starts blocking on its own, the stand that measures this fails and the warning has to be removed, rather than left to lie in the other direction.

Your own unpacked extension goes in a folder you can open from the app
The extensions folder is printed on the screen with a button that opens it. Put an unpacked extension in a folder named exactly as the badge on its card, then start the profile again.
For anything outside the eleven cards there is a link box. Paste a Chrome Web Store link and the same code that installs parses it, so the window cannot call a link bad that the install would have accepted, or the other way round.
Installed by link, the extension lands in a folder named store- plus its id, and it gets its own card, titled from its manifest rather than from that folder. Without that card the files would sit on disk with no switch to turn them on.
Remove deletes the folder and clears the choice from every profile that had it, and tells you how many. The files are shared by all profiles, so there is one copy and one version for everyone, while the on and off stays per profile.
What this does not do
- The catalog is eleven cards and there is no store search inside the app. Anything else you add by pasting a store link or by dropping the files in yourself.
- Nothing is bundled with the app. Every install downloads from the Chrome Web Store, so with no network there is no install and the failure says so.
- On the built-in engine a store extension does not change the page. Only the blocking rules ARMANOS executes itself work there, and rules it cannot parse are counted, not applied.
- Manifest V2 extensions are refused at install and at launch. There is no compatibility layer and none is planned in this part of the product.
- The files live in one folder shared by every profile, so all profiles run the same version of an extension. Only the on and off choice, and the per profile ceiling of 50, belong to the profile.
How to check
Open the file, then the stand that keeps it honest.
- The catalog is eleven entries, each with a store id, a version and a category, and each one really installs
- packages/shared/src/index.js · apps/desktop/test/catalog-installable.js
- The download is verified by signature and the extension keeps its store id
- apps/desktop/src/main/main.js · apps/desktop/test/ext-keeps-store-id.js
- Enable installs the files first, and says so when the choice did not reach the account
- apps/desktop/src/manager/store.js · apps/desktop/test/ext-choice-travels.js
- Only Manifest V3 is loaded, the folder name cannot escape the extensions directory, and a refusal becomes a notification
- apps/desktop/src/main/main.js · apps/desktop/test/extension-paths.js
- The built-in engine warning is shown exactly when the built-in engine will start, and it is measured, not assumed
- apps/desktop/src/manager/store.js · apps/desktop/test/extension-limits-honest.js
Put a blocker in the profile that needs one
The Free plan gives you two profiles, and the Extensions screen works without signing in.