Greasemonkey explained: where page scripts still make sense

Searching for Greasemonkey returns two unrelated things. One is a chain of oil change shops. The other is a Firefox add-on from 2005 that started an entire category of browser customisation, and which is still maintained: the listing on Mozilla's add-on site shows version 4.14, last updated in June 2026, with 157,711 users.

Twenty years is a long life for a browser extension, and the reason it has lasted is that it solves a problem nothing else has taken over. A web app that is used for six hours a day will have one thing wrong with it that its makers will never fix, because it only bothers a few hundred people. A page script fixes that one thing. Nothing else in the browser can.

What has changed is the landscape around it. Greasemonkey is now one of four managers, it runs in one browser, and Chrome has recently added a switch that has to be found before any of this works there at all.

What a user script actually is

A user script is a file of JavaScript, conventionally named with a .user.js ending, that a manager injects into pages the script says it wants. Greasemonkey's own description is exactly that: customise the way a web page displays or behaves, by using small bits of JavaScript.

The part that makes it a user script rather than a bookmarklet is a comment block at the top holding metadata. That block names the script, declares which URLs it applies to, states which privileged functions it wants, and can point at a location for automatic updates. The manager reads the block, decides which pages match, and runs the code at a point in the page lifecycle the script can also specify.

Two consequences are worth holding onto. First, the script runs inside the page, so it can see and change anything on that page, including whatever is on screen because somebody is signed in. Second, it runs every time a matching page loads, without being asked, which is why the matching rules deserve more attention than the code.

Four managers, three browsers

The single most common wasted hour is spent trying to install Greasemonkey in Chrome. It does not exist there. Greasy Fork, which is the main public repository for user scripts, lists the managers by browser, and the split is clear.

Manager Browsers Scale Notes
Greasemonkey Firefox only 157,711 users, version 4.14 The original, listed as also available for Firefox on Android
Violentmonkey Firefox, Chrome, Edge, Opera 187,302 users on Firefox, version 2.49.0 Open source under the MIT licence, with script ordering and import and export
Tampermonkey Chrome, Edge, Opera, Firefox, Safari About 12,000,000 users in the Chrome Web Store, version 5.5.0 The largest by a wide margin
Userscripts Safari, on Mac, iPhone and iPad Free on the App Store Open source, published by the quoid project

The scale difference between Tampermonkey and the others is not a quality judgement, it is a distribution fact: Tampermonkey is in the Chrome Web Store and Chrome is where most people are. For anyone choosing today, the honest summary is that the browser decides. Firefox users have all three of the first three options. Chrome and Edge users choose between Tampermonkey and Violentmonkey. Safari users choose between Tampermonkey and Userscripts.

Scripts themselves are mostly portable, because the managers implement the same metadata block and the same family of privileged functions. Mostly is not always, and a script that uses an unusual function or a manager-specific storage API will need editing. Anything written in the last few years and published on a public repository tends to work across managers without changes.

What changed in Chrome, and why scripts suddenly stopped running

This is the current source of confusion, and it has a precise answer in Chrome's own documentation.

Running arbitrary user code is now a permissioned capability. For Chrome versions before 138, the documentation states that users must enable Developer mode. From Chrome 138 onward there is a dedicated switch instead, called Allow User Scripts, which sits on each extension's own details page. The consequence is stated bluntly: if the Allow User Scripts toggle is not enabled, the scripting interface is undefined, which means the manager loads and does nothing.

That explains a symptom that looks like a broken extension. The manager's icon appears, the script list shows the scripts, and no script has any effect on any page. Nothing in the manager's interface is wrong, and no amount of reinstalling changes it.

The switch is per extension, not global, so installing a second manager means finding the toggle again. It also survives updates unevenly across managed machines, so on a Mac under mobile device management the toggle may be off and not changeable, in which case Firefox or Safari with its own manager is the realistic route rather than an argument with the policy.

Where a page script is still the right tool

A useful way to decide is to ask what else could do the job, in order of increasing effort.

If the change is purely visual, a user style is simpler and safer than a script. Hiding a promotional banner, widening a cramped column or changing a font size is a matter of CSS, and a style cannot read a page or send anything anywhere. Several of the managers handle styles as well as scripts, and Safari's Userscripts is explicitly a manager for both.

If the change needs to react to what is on the page, a script is the tool. Examples that come up repeatedly: putting a total at the top of a list that only shows per-row numbers, adding a keyboard shortcut to a web app that has none, marking rows that match a condition the site cannot filter on, stripping tracking parameters from links before they are copied, or pulling a value out of one system so it can be pasted into another without retyping.

If the change needs to persist across sites, run on a schedule, or touch anything outside the browser, it has outgrown a script. That is an extension, or a small program with API access, and forcing it into a page script produces something fragile that breaks on the next redesign.

The honest limit of user scripts is that they depend on the page's structure, and the page's structure is not a contract. A script that finds an element by its class name will break silently when the site's build tool generates a new class name, which happens without announcement. Anyone maintaining more than a handful of scripts spends real time on this, and that maintenance cost is the main reason to keep the collection small.

A short test for which tool to reach for

Three questions settle it quickly. Does the change only affect appearance? Then it is a style. Does it need to read the page and do something conditional? Then it is a script. Does it need to keep working when the tab is closed, or run against several sites in a coordinated way? Then it is not a page script and building it as one will cost more than building it properly.

The last question is the one that gets answered wrongly, usually because a script already exists and an extension does not. A script that has grown to four hundred lines, keeps its own state and reaches across two services is an application living in the wrong place, and it will be rewritten eventually. Noticing that early saves the rewrite.

The permission question that deserves more attention than it gets

A user script runs inside the page with the page's privileges. On a page where a mail account, a payroll system or a cloud console is open, the script can read what is on screen and act as the signed-in user. That is not a flaw, it is what makes the tool useful, and it is also why the matching rules matter.

Three habits cover most of the risk.

Read the script before installing it. Most useful scripts are under a hundred lines, and the metadata block is the part to read first: a script that claims to fix one site but matches all sites is worth closing. Scripts that request the privileged function for cross-origin requests can send page data elsewhere, which may be legitimate and is worth understanding rather than skipping.

Narrow the match. A script written for one page of one site should be limited to that path rather than the whole domain, and most managers allow the rules to be edited after installing. This also reduces breakage, since fewer pages means fewer redesigns that matter.

Keep automatic updates in view. Automatic updating is a feature of the managers and it is genuinely useful for keeping a script working, and it also means code can change after being reviewed. For a script that runs on a page where money or personal data is visible, pinning it and updating deliberately is the more careful setting.

Where scripts come from

Two public repositories carry most of what people install: Greasy Fork, which is the one the managers themselves point at, and OpenUserJS. Both host scripts written by other users, which means the quality range is wide and the review is community review rather than a vendor's.

That is worth stating plainly because it changes how the choice should be made. A script with a long history, visible source, an active issue discussion and recent updates is a reasonable bet. A script with no comments, no update in years and a match rule covering every site is not, however well its description reads. The description is written by the same person who wrote the code, and the code is the part that runs.

Scoping scripts to one window rather than the whole browser

There is a structural point that follows from all of the above. A script manager is installed into a browser, and its scripts then apply to every window and every session in that browser. For someone who uses one browser for one job, that is fine.

For anyone whose browser holds several accounts of the same service, it is not. A script that rewrites a view in a work account will also rewrite it in a personal account, and a script that pulls a value out of one system to paste into another will run in a client's tenant as readily as in the home one. Narrowing the match rules helps when the accounts live on different domains and does nothing when they do not, because the URL is identical and only the session differs.

The arrangement that solves it is separation at the window level: each app in its own window with its own session, and customisation applied to the window that needs it rather than to the whole browser. That is what a browser built around per-app workspaces provides, and the features page covers how the sessions are kept apart. For heavier automation than a page script can carry, a built-in terminal is the other half of the same idea, since the work moves out of the page and into a place where it can be read and version controlled.

What to change first

Start by finding out whether scripts run at all: in Chrome, open the manager's details page and look for the Allow User Scripts toggle, because a manager without it is inert. Then take the single most irritating thing about the web app used most, check Greasy Fork for an existing script, and read its metadata block before installing it. If the same app is used under two accounts, sort the sessions out before adding scripts, which a browser such as SpaceDeck does by giving each account its own window.

Frequently asked questions

Does Greasemonkey work in Chrome?

No. Greasemonkey is a Firefox add-on and is not published for Chrome. Greasy Fork lists Tampermonkey and Violentmonkey as the managers for Chrome, Edge and Opera, so a script written for Greasemonkey is normally installed into one of those instead.

Why do the scripts do nothing after installing a manager in Chrome?

Most often because user scripts are gated behind a switch. Chrome's documentation states that versions before 138 require Developer mode, and that from Chrome 138 onward each extension's details page has an Allow User Scripts toggle, without which the scripting interface is undefined.

Is there a user script manager for Safari?

Yes, two. Greasy Fork lists Tampermonkey and Userscripts for Safari. Userscripts is free on the App Store, open source, and runs on Mac, iPhone and iPad as a manager for both scripts and styles.

Are user scripts safe to install?

They run inside the page with the signed-in user's privileges, so the answer depends on the script. Reading the code before installing, checking that the match rules cover only the pages intended, and being deliberate about automatic updates cover most of the risk.

Will a script written for Greasemonkey run in Tampermonkey or Violentmonkey?

Usually, because the managers share the same metadata block and the same family of privileged functions. Scripts that rely on a manager-specific storage or update API are the exception and need small edits.

Back to all posts