A metadata block is a section of a User script that does not execute any code, but describes the script. The main metadata block is called the UserScript metadata block and typically contains the script name, namespace, description, and Script injection rules.
Any metadata blocks appear in JavaScript comments and may appear anywhere in the top level Greasemonkey code scope of the script, but is usually near the top of the file. It begins with the line:
// ==UserScript==
... and ends with:
// ==/UserScript==
Additional configuration is always between those lines is in the format of:
// @key value
If this metadata block includes a key that Greasemonkey does not understand or tab characters, it will simply be ignored. Code may also occur in-between the header and footer comments. The header comment must always begin on a newline and have no whitespace preceding except for a newline in the text stream. Nested UserScript metadata blocks are not supported. Key names are typically constructed from alphanumeric characters and are case sensitive.
User script hosting sites may utilize a XML styled name prefix to identify the origin of the key. An example of this is prefix:key.
Some sites also support their own evolved metadata block, such as OpenUserJS.org, to minimize collisions with other sites and UserScript engines that define their own standards:
// ==OpenUserJS==
... and ends with:
// ==/OpenUserJS==
Additional site specific configuration is always between those lines is in the format of:
// @key value
Some sites also offer a cross-site compatible metadata block for including library scripts with:
// ==UserLibrary==
... and ends with:
// ==/UserLibrary==
Additional library specific configuration is always between those lines is in the format of:
// @key value
⬆ ⬇ | Other Keys | Examples | Caveats | See Also | Notes
// ==UserScript==
// @key value
// ==/UserScript==
// ==OpenUserJS==
// @key value
// ==/OpenUserJS==
Value: Object
Compatibility: Greasemonkey 0.2.5+
Keys
| Properties | ||||
|---|---|---|---|---|
| @name | @run-at | @require | @version | |
| @namespace | @include | @resource | @updateURL | |
| @description | @exclude | @grant | @installURL | |
| @icon | @match | @unwrap | @downloadURL | |
| @author | @noframes | |||
| @homepageURL | 
Blocks: UserScript / UserLibrary
Value: String
Compatibility: Greasemonkey 0.2.5+
Usage:
// @name My Script
Compatibility: Greasemonkey 2.2.0+
Usage:
// @name My Script
// @name:cs    Můj skript
// @name:es-MX Mi guión 
// @name:ru    Мой сценарий
Blocks: UserScript
Value: String
Usage:
// @namespace https://www.example.com/gmscripts
While the namespace is non-semantic, it should be your prefered internet homepage URI according to the W3C standards specification. If no namespace is provided, it is assumed to be the domain from which the script is installed. Since a script can live on various servers or on a local file system, authors may choose to omit this key when publishing on userscripts.org⁸⁰⁸⁰⋔ and let Greasemonkey supply one automatically. If you are creating one locally, authors may choose the URI specification standard of http://localhost for the value as being an anonymous local script.
Common String Values
Script Host Chosen Namespace via Greasemonkey
Usage: Omitted @namespace in source userscript file
https://userscripts.org/scripts/source/scriptid.user.js maps to// @namespace userscripts.orghttps://example.org/scripts/filename.user.js maps to// @namespace example.orghttp://localhost/scripts/filename.user.js maps to// @namespace localhosttag URI
Usage: "tag:" taggingEntity ":" specific [ "#" fragment ]
// @namespace tag:johndoe@example.com,2009:johndoe// @namespace tag:johndoe@example.net,2010-05:johndoe/pathto// @namespace tag:userscripts.org,2005-06-19T23:33:49Z:JohnDoe:DescriptionWithNoSpaces:etc:etc:etcid [[ " + " id ], [ " + " id ], ...]// @namespace anotherjesse// @namespace userid + vanityid + Firstname Lastnamescheme "://" domain [ "." tld ][ "/" pathto ]// @namespace http://localhost// @namespace http://localhost.localdomain// @namespace https://userscripts.org/users/userid// @namespace https://example.org/pathto/scriptThe NoScript Security Suite add-on currently utilizes namespace filtering, and may sanitize user scripts that are not listed in the XSS white-list section of the options dialog.
Blocks: UserScript / UserLibrary
Value: String
Usage:
// @description This script even does the laundry!
Blocks: UserScript
Value: URL
Compatibility: Greasemonkey 0.9.0+
Usage:
// @icon https://example.com/icon.png
Blocks: UserScript / OpenUserJS
Value: String
Compatibility: Greasemonkey 3.5.0+
Usage:
■ UserScript
// @author Author <Author email> (Author Website)
■ OpenUserJS
// @author sizzle
Blocks: UserScript
Value: URI
Compatibility: Greasemonkey 3.5.0+
Usage:
// @homepageURL https://example.com
 OpenUserJs.org allows http, https and mailto protocols.
 OpenUserJs.org allows http, https and mailto protocols.Blocks: UserScript
Value: String
Compatibility: Greasemonkey 0.9.8+
Usage:
// @run-at document-end
Default: document-end
document-end and is suitable for most situations. It is not required to insert this into the metadata block as this key/value pair is the default. However some scripts may benefit from early injection at the document-start.Blocks: UserScript
Value: String
Usage:
// @include https://www.example.com/*
Blocks: UserScript
Value: String
Usage:
// @exclude https://www.example.com/foo/*
Blocks: UserScript
Value: String
Compatibility: Greasemonkey 0.9.8+
Usage:
// @match https://www.example.com/foo/*
Blocks: UserScript
Value: undefined
Compatibility: Greasemonkey 2.3.0+
Usage:
// @noframes
Blocks: UserScript
Value: String
Compatibility: Greasemonkey 0.8.0+
Usage:
// @require foo.js
Blocks: UserScript
Value: String
Compatibility: Greasemonkey 0.8.0+
Usage:
// @resource resourceName https://www.example.com/resource.png
Blocks: UserScript
Value: String
Compatibility: Greasemonkey 1.0+
Usage:
// @grant GM_addStyle
// @grant GM_deleteValue
// @grant GM_getResourceText
// @grant GM_getResourceURL
// @grant GM_getValue
// @grant GM_listValues
// @grant GM_log
// @grant GM_openInTab
// @grant GM_registerMenuCommand
// @grant GM_setClipboard
// @grant GM_setValue
// @grant GM_xmlhttpRequest
// @grant unsafeWindow
or
// @grant none
// @grant none will be the default. If using // @grant none the code will be assumed to run in the restricted (content scope) namespace.// @grant none may be prone to detection by their respective target sites that they are injected into. There are additional considerations if using a framework like jQuery or YUI in a user script and the target site also uses one of them.Blocks: UserScript
Value: undefined
Compatibility: Greasemonkey 0.8.1 - 0.9.22
Usage:
// @unwrap
(function(){ /* script source */ })();var sidebar = "foo";. This will return a script error of Illegal value, and script execution will cease. See also greasemonkey.dejavu.com#108.Blocks: UserScript / UserLibrary
Value: String or Number
Compatibility: Greasemonkey 0.9.0+
Usage:
// @version 0.0.1
Blocks: UserScript
Value: URL
Compatibility: Greasemonkey 0.9.12+
Usage:
// @updateURL https://www.example.com/script.user.js
or
// @updateURL https://userscripts.org/scripts/source/scriptid.meta.js
text/x-userscript-meta,  should automatically be sent internally to reduce bandwidth and a quicker response by returning only the Metadata Block components supported from the host. Minimal requirement for a successful response is a @version line inside the UserScript metadata block.If this key is set when publishing to userscripts.org⁸⁰⁸⁰⋔, it is highly recommended to use the meta.js routine URL (See the second usage example above... changing scriptid to your current numerical scriptid). This ensures that other Greasemonkey clones are following userscripts.org guidelines for update checking. This helps to prevent DoS and DDoS attacks for those clones that may implement script updating improperly.
NOTE: Some upstream releases of Greasemonkey may not be properly detecting the userscripts.org @updateURL and may be using a special CDN to intercept some of your daily update checks. If you wish to bypass this remote domain by restoring proper usage of the meta.js routine on userscripts.org please use this remote forks repository with the following git commands, or if available in the files section of this project. Remember to manually check for updates in Firefox otherwise next release will automatically be from upstream.:
$ git clone git://git.code.sf.net/p/greasemonkey/code greasemonkey
$ cd greasemonkey
$ git checkout slave
$ ./build.sh official
Compatibility: Greasemonkey 0.9.12+
Compatibility: Greasemonkey 0.9.14+
Blocks: UserScript
Value: URL
Usage:
// @downloadURL https://www.example.com/script.user.js
or
// @downloadURL https://userscripts.org/scripts/source/scriptid.user.js
Some Userscripts contain other special keys in the metadata blocks.
These unsupported metadata keys are ignored by the Greasemonkey extension, but can be read by human beings or utilized by other code and site configurations.
Keys
Properties
Blocks: UserScript / UserLibrary
Value: String
Usage:
// @copyright Year, Author (Author Website)
// @copyright 2009+, John Doe (https://www.example.com/projecthomepage)Blocks: UserScript / UserLibrary
Value: String
Usage:
// @license License Type; License Homepage
// @license CC-BY-NC-SA-4.0; https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode// @license GPL-3.0-or-later; https://www.gnu.org/licenses/gpl-3.0.txtBlocks: UserScript
Value: URI
Usage:
// @supportURL https://example.com/mysupport
 OpenUserJs.org allows http, https and mailto protocols.
 OpenUserJs.org allows http, https and mailto protocols.Status: End of Life 2015 08 24
Value: String
Usage:
// @oujs:author Username
Status: End of Life 2015 08 24
Value: String
Usage:
// @oujs:collaborator Username
Blocks: UserScript
Value: String or Number
Usage:
// @uso:script scriptid
https://userscripts.org/scripts/source/scriptid.meta.jsBlocks: UserScript
Value: String or Number
Usage:
// @uso:version versionid
https://userscripts.org/scripts/source/scriptid.meta.jsBlocks: UserScript
Value: String
Usage:
// @uso:timestamp Wed, 17 Jun 2009 22:50:26 +0000
https://userscripts.org/scripts/source/scriptid.meta.jsBlocks: UserScript
Value: String
Usage:
// @uso:hash 30d54f8ba24c0c6ec5710866e9b0839b2066a815
https://userscripts.org/scripts/source/scriptid.meta.jsBlocks: UserScript
Value: String or Number
Usage:
// @uso:rating 4.00
https://userscripts.org/scripts/source/_scriptid_.meta.jsBlocks: UserScript
Value: String or Number
Usage:
// @uso:installs count
// @uso:reviews count
// @uso:discussions count
// @uso:fans count
https://userscripts.org/scripts/source/scriptid.meta.jsBlocks: UserScript
Value: String
Usage:
// @uso:unlisted
Blocks: UserScript
Value: String
Usage:
// @attribution Attribution Name (Attribution Script Homepage)
// @attribution Jane Doe (https://www.example.com/janedoe/scriptid)
// @attribution Jack Doe (https://www.example.com/jackdoe/scriptid)
// @attribution Jill Doe (https://www.example.com/jilldoe/scriptid)
Blocks: UserScript
Value: String
Usage:
// @contributor Contributor Name (Contributor Homepage)
// @contributor Jane Doe (https://www.example.com/janedoe)// @contributor Jack Doe (https://www.example.com/jackdoe)// @contributor Jill Doe (https://www.example.com/jilldoe)Blocks: OpenUserJS
Value: String
Usage:
// @collaborator Marti
Blocks: OpenUserJS
Value: String
Usage:
// @unstableMinify A brief technical reason
Blocks: UserScript
Value: Number or String
Usage:
// @major 0
Blocks: UserScript
Value: Number or String
Usage:
// @minor 0
Blocks: UserScript
Value: Number or String
Usage:
// @build 1
⬆ ⬇ | Multiplexing Metadata Blocks | Knowing Your Own Metadata | jQuery require
// ==UserScript==
// @name          My Script
// @namespace     https://www.example.com/gmscripts
// @description   Scripting is fun
// @include       https://www.example.com/*
// @include       https://www.example.org/*
// @exclude       https://www.example.org/foo
// @require       foo.js
// @resource      resourceName1 resource1.png
// @resource      resourceName2 https://www.example.com/resource2.png
// ==/UserScript==
// ==OpenUserJS==
// @author sizzle
// @collaborator Marti
// ==/OpenUserJS==
Some sites require mirroring certain keys in multiple blocks. OpenUserJS.org is an example. Take their "Getting Started with a User Library" example.
Typically one can write this as two separate blocks like this:
// ==UserScript==
// @namespace     https://openuserjs.org/users/username
// @exclude       *
// @name          Getting Started with a User Library
// @description   Showing the current basic and recommended format for a Library script
// @copyright     2017, User Name (https://openuserjs.org/users/username)
// @license       MIT
// @version       0.0.0
// ==/UserScript==
// ==UserLibrary==
// @name          Getting Started with a User Library
// @description   Showing the current basic and recommended format for a Library script
// @copyright     2017, User Name (https://openuserjs.org/users/username)
// @license       MIT
// @version       0.0.0
// ==/UserLibrary==
... however a more convenient method to keep these keys syncronized between the blocks is to do this:
// ==UserScript==
// @namespace     https://openuserjs.org/users/username
// @exclude       *
// ==UserLibrary==
// @name          Getting Started with a User Library
// @description   Showing the current basic and recommended format for a Library script
// @copyright     2017, User Name (https://openuserjs.org/users/username)
// @license       MIT
// @version       0.0.0
// ==/UserScript==
// ==/UserLibrary==
Logical Control Flow
Methodology
| Preparation | Restructuring | Implementation | 
|---|---|---|
| Starting a restructure | with Function Expression | Finishing a restructure | 
| with E4X XMLList | ||
| with ES6+ Template Literals | ||
| with GM_info | 
Begin by including this L/GPL 3.0 or later code snippet in your source which analyzes the native UserScript Metadata Block and returns a restructured Object in the JSON compatible format.
function parseHeaders(metadataBlock) {
  metadataBlock = metadataBlock.toString();
  var re = /^\/\/ @(\S+)(?:\s+(.*))?/;
  var headers = {};
  var name, prefix, header, key, value;
    var lines = metadataBlock.split(/[\r\n]+/).filter(function (e, i, a) {
      return (e.match(re));
    });
    for (var line in lines) {
      [, name, value] = lines[line].replace(/\s+$/, "").match(re);
      switch (name) {
        case "licence":
          name = "license";
          break;
      }
      [key, prefix] = name.split(/:/).reverse();
      if (key) {
        if (prefix) {
          if (!headers[prefix])
            headers[prefix] = new Object;
          header = headers[prefix];
        }
        else
          header = headers;
        if (header[key]) {
          if (!(header[key] instanceof Array))
            header[key] = new Array(header[key]);
          header[key].push(value || "");
        }
        else
          header[key] = value || "";
      }
    }
    if (headers["license"])
      headers["licence"] = headers["license"];
  return headers;
}
Encase the UserScript Metadata Block in a Function Expression (FE) and pass to the parsing routine.
  var fileMETA = parseHeaders((function () {
// ==UserScript==
// @name          My Script
// @namespace     https://www.example.com/gmscripts
// @description   Scripting is fun
// @copyright     2009+, John Doe (https://www.example.com/~jdoe)
// @license       GPL-3.0-or-later; https://www.gnu.org/licenses/gpl-3.0.txt
// @version       0.0.1
// @include       https://www.example.com/*
// @include       https://www.example.org/*
// @exclude       https://www.example.org/foo
// @require       foo.js
// @resource      resourceName1 resource1.png
// @resource      resourceName2 https://www.example.com/resource2.png
// @grant         GM_log
// @grant         GM_xmlhttpRequest
// @uso:script    scriptid
// ==/UserScript==
  }));
Encase the UserScript Metadata Block in a CDATA tag group and pass to the parsing routine.
IMPORTANT: E4X has been deprecated and disabled on Mozilla Firefox 17+ versions and is slated to be removed by version 18 release.
If a user omits a Greasemonkey supplied key such as @namespace then it will not be reflected in this copy.
  var fileMETA = parseHeaders(<><![CDATA[
// ==UserScript==
// @name          My Script
// @namespace     https://www.example.com/gmscripts
// @description   Scripting is fun
// @copyright     2009+, John Doe (https://www.example.com/~jdoe)
// @license       GPL-3.0-or-later; https://www.gnu.org/licenses/gpl-3.0.txt
// @version       0.0.2
// @include       https://www.example.com/*
// @include       https://www.example.org/*
// @exclude       https://www.example.org/foo
// @require       foo.js
// @resource      resourceName1 resource1.png
// @resource      resourceName2 https://www.example.com/resource2.png
// @grant         GM_log
// @grant         GM_xmlhttpRequest
// @uso:script    scriptid
// ==/UserScript==
]]></>.toString()
  );
Encase the UserScript Metadata Block in back apostrophes, a.k.a back ticks, to treat it as a multi-line text block.
  var fileMETA = parseHeaders(`
// ==UserScript==
// @name          My Script
// @namespace     https://www.example.com/gmscripts
// @description   Scripting is fun
// @copyright     2009+, John Doe (https://www.example.com/~jdoe)
// @license       GPL-3.0-or-later; https://www.gnu.org/licenses/gpl-3.0.txt
// @version       0.0.3
// @include       https://www.example.com/*
// @include       https://www.example.org/*
// @exclude       https://www.example.org/foo
// @require       foo.js
// @resource      resourceName1 resource1.png
// @resource      resourceName2 https://www.example.com/resource2.png
// @grant         none
// @uso:script    scriptid
// ==/UserScript==
`
  );
The last known native UserScript Metadata Block is available with GM_info. Retrieve this String and pass to the parsing routine.
GM_info.script may have some scoping issues with certain Object types such as iterating over the @resource values contained in GM_info.script.resources with for…in
// ==UserScript==
// @name          My Script
// @namespace     https://www.example.com/gmscripts
// @description   Scripting is fun
// @copyright     2009+, John Doe (https://www.example.com/~jdoe)
// @license       GPL-3.0-or-later; https://www.gnu.org/licenses/gpl-3.0.txt
// @version       0.0.4
// @include       https://www.example.com/*
// @include       https://www.example.org/*
// @exclude       https://www.example.org/foo
// @require       foo.js
// @resource      resourceName1 resource1.png
// @resource      resourceName2 https://www.example.com/resource2.png
// @grant         GM_log
// @grant         GM_xmlhttpRequest
// @uso:script    scriptid
// ==/UserScript==
  var fileMETA = parseHeaders(
    GM_info.scriptMetaStr
    /* These methods are optional and mutually inclusive for tidiness */
    .trim().split(/\n/).map(function (e) { return e.trim(); }).join("\n")
  );
Using GM_xmlhttpRequest to retrieve the meta.js routine from userscripts.org⁸⁰⁸⁰⋔ implement and display name/value pairings to the console.
GM_xmlhttpRequest({
  method:"GET",
  url:"https://userscripts.org/scripts/source/" + fileMETA["uso"]["script"] + ".meta.js",
  headers:{
    "Accept":"text/javascript; charset=UTF-8"
  },
  overrideMimeType:"application/javascript; charset=UTF-8",
  onload:function(response) {
    var httpsMETA = parseHeaders(response.responseText);
    GM_log([
      "\n---------- Local ----------",
      fileMETA["name"] + " version " + fileMETA["version"],
      fileMETA["copyright"],
      fileMETA["license"],
      fileMETA["description"],
      fileMETA["include"],
      fileMETA["exclude"],
      "\n---------- Remote ----------",
      httpsMETA["name"] + " version " + httpsMETA["version"],
      httpsMETA["copyright"],
      httpsMETA["license"],
      httpsMETA["description"],
      httpsMETA["include"],
      httpsMETA["exclude"],
      httpsMETA["uso"]["script"],
      httpsMETA["uso"]["version"],
      httpsMETA["uso"]["timestamp"],
      httpsMETA["uso"]["hash"],
      httpsMETA["uso"]["installs"],
      httpsMETA["uso"]["reviews"],
      httpsMETA["uso"]["rating"],
      httpsMETA["uso"]["discussions"],
      httpsMETA["uso"]["fans"]
    ].join("\n"));
  }
});
// ==UserScript==
// @name          Hello jQuery
// @namespace     https://www.example.com/examples
// @description   jQuery test script
// @include       *
// @require       https://code.jquery.com/jquery-latest.js
// @grant         none
// ==/UserScript==
/* jshint esversion: 5 */
/* globals $, jQuery */
this.$ = this.jQuery = jQuery.noConflict(true);
$(document).ready(function() {
  $("a").click(function() {
    alert('Hello world!');
  });
});
    
      
        
        
          
        
      
      Wiki: GM_getResourceText
    
      
        
        
          
        
      
      Wiki: GM_getResourceURL
    
      
        
        
          
        
      
      Wiki: GM_info
    
      
        
        
          
        
      
      Wiki: Greasemonkey_Manual:API
    
      
        
        
          
        
      
      Wiki: Greasemonkey_Manual:Creating_Scripts
    
      
        
        
          
        
      
      Wiki: Greasemonkey_Manual:Environment
    
      
        
        
          
        
      
      Wiki: Greasemonkey_Manual:Managing_Scripts
    
      
        
        
          
        
      
      Wiki: Main_Page
    
      
        
        
          
        
      
      Wiki: Metadata_Block
    
      
        
        
          
        
      
      Wiki: Script_injection_rules
    
      
        
        
          
        
      
      Wiki: Scripts_directory
    
      
        
        
          
        
      
      Wiki: User_script
    
      
        
        
          
        
      
      Wiki: Version_history#10
    
      
        
        
          
        
      
      Wiki: XPCNativeWrapper
    
      
        
        
          
        
      
      Wiki: config.xml