What Does the @run-at Directive Specify in Userscripts?
The @run-at directive in a userscript metadata block
specifies the exact moment during the page loading process that the
script should execute. By controlling whether a script runs before the
page’s DOM starts loading, while it is building, or after the entire
page and its external assets have finished loading, @run-at
helps developers ensure their scripts run at the optimal time for
performance and DOM availability.
Understanding the Common
@run-at Values
Userscript managers (such as Tampermonkey, Violentmonkey, or
Greasemonkey) support several predefined values for
@run-at. Selecting the correct value depends on whether
your code needs early access to interrupt page scripts or full access to
the rendered HTML elements.
1. document-start
Execution Moment: The script runs as early as possible, before any document parsing or DOM construction begins.
Best Used For: * Injecting custom CSS styles before the page renders to prevent visual flickering (Flash of Unstyled Content).
Overriding global JavaScript functions or APIs before the site’s own scripts can execute.
Caveat: The DOM (
document.body) does not exist yet when this code runs, so you cannot select or modify HTML elements directly without waiting for them.
2. document-body
- Execution Moment: The script runs as soon as the
<body>element is created and added to the DOM. - Best Used For: Injecting elements directly into the
<body>before the rest of the page’s lower elements or scripts load. - Caveat: Sub-elements inside the body may still be loading, so specific target elements lower on the page might not be accessible yet.
3. document-end
- Execution Moment: The script runs while the DOM is being constructed or immediately after the DOM layout is complete, but before sub-resources like images and frames have necessarily finished loading.
- Best Used For: Most standard user scripts. It provides a good balance between early execution and having full access to the page’s HTML structure.
- Caveat: External assets like images or dynamic asynchronous content loaded via API calls might not be ready.
4. document-idle
(Default)
Execution Moment: The script runs after the document and all associated resources (images, stylesheets, frames) have fully loaded, or right after the
DOMContentLoadedevent triggers.Best Used For: * Scripts that manipulate complex UI elements.
Operations that do not require urgent execution and can wait for the network to settle.
Default Behavior: If you omit the
@run-atdirective entirely from your metadata block, userscript managers typically default todocument-idle.
5. context-menu
- Execution Moment: The script does not run automatically on page load. Instead, it appears as an option in the browser’s context menu (right-click menu) or the userscript manager menu, running only when manually clicked by the user.
- Best Used For: On-demand utilities, such as downloading specific media, analyzing selected text, or triggering manual page transformations.
How to Set
@run-at in Your Metadata Block
You declare @run-at inside the top metadata block of
your userscript file alongside other directives like @name
and @match.
// ==UserScript==
// @name Custom Style Injector
// @namespace http://tampermonkey.net/
// @version 1.0
// @match https://example.com/*
// @run-at document-start
// @grant none
// ==UserScript==
// Your code runs immediately before the DOM starts parsing
console.log("Running at document-start!");How to Choose the Right Setting
- Choose
document-startif you are blocking elements, injecting global styles, or modifying browser APIs. - Choose
document-endordocument-idleif your script relies on reading or modifying existing HTML tags, buttons, or text on the page.