Features in Userscript Generator

Table of Contents

Userscript Generator is a Yeoman generator to quickly initiate a new project for a userscript.

See Using modern syntax for the usage.

In this post we will dive into each feature and see why and how we use it, and whether we have different choices.

CSS modules

Both global CSS (e.g. style.css) and CSS modules (e.g. style.module.css) are supported.

A userscript usually works in different websites which may not be maintained by the script developer. So if the script provides independent UI in the website, it must be careful not to break the website and not to be broken by the website. We have two choices, shadow DOM and CSS modules.

  • Option 1: Shadow DOM
    • Pros: Neat class names, no repeated prefix.
    • Cons: It doesn't always work because the CSS can only be injected inside the shadow DOM root, which may be blocked by the CSP.
  • Option 2: CSS modules
    • Pros: It can bypass the CSP issue because the CSS can be injected with the GM_addStyle API.
    • Cons: More code required, less readable class names in the DOM.

So if you expect your script to work in many different websites including those protected by CSP, CSS modules might be a better choice. Otherwise use global CSS with shadow DOM for simplicity.


UnoCSS is similar to TailwindCSS but arguably more flexible and reliable.

At the time of writing, TailwindCSS does not work well for userscripts, because it either injects reset CSS breaking the style of the host, or misses default values leading to invalid CSS output. This is a bug and has occurred before.

By using UnoCSS or its alternatives, the effort of maintaining CSS code is significantly reduced.

We just write class names based on what we need, and the CSS code will be generated automatically. If later we don't need this class name any more, the related CSS code will also be pruned.


SolidJS is a light-weight UI library. It has some similarities with React, but much lighter and easier to use for a small project like a userscript.

However, SolidJS doesn't have an official UMD or IIFE package. In other words, there is no easy way for us to import SolidJS as a single file resource using @require.

We have several options here:

  • Option 1: import it and bundle it in the userscript.

    • Pros: Simple to go.
    • Cons: Bloated userscript size and worse readability.
  • Option 2: import it using dynamic import at runtime.

    • Pros: Better readability, smaller file size.
    • Cons: An obvious delay before the UI appears.
    • Suggestion: If the delay is acceptable, this might be a good choice.
  • Option 3: compile SolidJS as a UMD package and use it in different scripts.

    This is exactly what I have done in the generator. Check the compiled file at jsdelivr and the source code at @violentmonkey/dom.

    • Pros: Good readability, smaller file size, fast loading, reusable common assets between different scripts.
    • Cons: Need to maintain an extra file, and it might not always be up-to-date.

Absolutely, every decision involves a trade-off, and ultimately, you have to make your own choices.


Thanks to the powerful tools, the development of a userscript is getting much smoother.

We can use the generator above to quickly create a new userscript with modern tech stack.

Published at August 24, 2023
Open Chat