Skip to content

[feat] migrate userscript loader to ESM #2791

Open

Description

@loynoir

feat

modern ESM for content scripts and userscripts

what changed

Basic assumption of JS library format have changed.

Many years ago, it's OK to assume dependency JS library is written in global IIFE.

Since 2021, famous dev like sindresorhus already migrated to ESM.

Now, popular library I known are written in ESM.

Now, I think, basic assumption of JS library format have changed from global IIFE to ESM.

current

  • userscript using legacy IIFE
  • userscript depends on legacy IIFE

foo.user.d.ts

/// <reference lib="DOM" />
/// <reference types="https://esm.sh/@types/tampermonkey@5.0.5" />
// /// <reference types="https://esm.sh/@types/greasemonkey@4.0.7" />
// /// <reference types="https://esm.sh/@violentmonkey/types@0.3.3" />

declare const JSZip: typeof import("https://esm.sh/jszip@3.10.1");
declare const Vue: typeof import("https://esm.sh/vue@3.5.35");

foo.user.js

// ==UserScript==
// @name hello
// @match *://*/*
// @require https://cdn.jsdelivr.net/npm/jszip@3.10.1/dist/jszip.min.js
// @require https://cdn.jsdelivr.net/npm/vue@3.5.35/dist/vue.runtime.global.prod.js
// @grant GM_notification
// ==/UserScript==

// @ts-check
/// <reference types="./foo.user.d.ts" />

(function () {
  "use strict";

  GM.notification(`Vue: ${Vue.version} JSZip: ${JSZip.version}`, "test");
})();

feature request

  • userscript using modern ESM
  • userscript depends on modern ESM

foo.user.mjs

// ==UserScript==
// @name hello
// @match *://*/*
// @grant GM_notification
// ==/UserScript==

// @ts-check
/// <reference lib="DOM" />
// @ts-expect-error: TBD, like `node:XXX`
import { notification } from `userscript:GM`
import JSZip from "https://esm.sh/jszip@3.10.1";
import Vue from "https://esm.sh/vue@3.5.35"

notification(`Vue: ${Vue.version} JSZip: ${JSZip.version}`, "test");

related

greasemonkey/greasemonkey#3229

#2791

violentmonkey/violentmonkey#2528

https://connect.mozilla.org/t5/ideas/enable-consuming-of-es-modules-in-content-scripts-and/idi-p/125953

tc39/ecma262#3877

Activity

  1. changed the title [-][feat] migrate userscript engine to ESM[/-] [+][feat] migrate userscript loader to ESM[/+] on May 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions