How Do Userscripts Store Data Across Browser Sessions?
Userscripts manage persistent data storage across browser sessions
primarily by leveraging specialized API functions provided by extension
managers like Tampermonkey or Violentmonkey, as well as native web
storage APIs. While standard web mechanisms like
localStorage and IndexedDB bind data strictly
to a single domain, userscript-specific APIs allow developers to store
preferences, tokens, and state variables securely across different
domains or script updates. Understanding how these storage mechanisms
differ—particularly in scope, security, and persistence—is essential for
building reliable, cross-session browser scripts.
Native Web Storage vs. Userscript APIs
When developing a userscript, you generally choose between standard browser APIs and userscript-manager APIs. Each serves distinct use cases depending on whether your script runs on a single site or across multiple domains.
1. Web Storage APIs
(localStorage & IndexedDB)
These are the standard storage methods built directly into modern web browsers.
localStorage: Stores key-value pairs as strings. It persists until explicitly cleared by the user or script.IndexedDB: A low-level API for structured, client-side storage of significant amounts of data, including files and blobs.
Key Limitation: Web Storage APIs are bound by the Same-Origin Policy. Data stored on
example.comvialocalStoragecannot be accessed when the script runs onanother-domain.com. Additionally, domain scripts can potentially access or modify data stored inlocalStorage.
2.
Userscript Manager Storage (GM_setValue &
GM_getValue)
Userscript managers (such as Tampermonkey, Violentmonkey, and Greasemonkey) provide dedicated storage APIs that bypass same-origin restrictions and isolate your script’s data from the host website.
GM_setValue(key, value): Asynchronously or synchronously saves a value tied specifically to the userscript, regardless of the active web page.GM_getValue(key, defaultValue): Retrieves a previously saved value associated with the specified key.GM_deleteValue(key): Removes a stored key-value pair.GM_listValues(): Returns an array of all keys stored by the script.
Comparison of Storage Methods
| Storage Method | Domain Scope | Security / Isolation | Data Capacity | Best Used For |
|---|---|---|---|---|
localStorage |
Single Origin | Accessible by host site scripts | ~5MB per origin | Simple, non-sensitive site-specific settings |
IndexedDB |
Single Origin | Accessible by host site scripts | High (dependent on disk space) | Large datasets or complex object storage on one domain |
GM_setValue |
Global (Cross-Domain) | Isolated from host site scripts | Generous (managed by browser extension) | User preferences, API keys, and cross-site state tracking |
Requiring Permissions for GM Functions
To use the dedicated userscript storage functions, you must
explicitly declare them in the script’s metadata block using the
@grant directive:
// ==UserScript==
// @name Persistent Data Example
// @namespace http://tampermonkey.net/
// @version 1.0
// @match https://*/*
// @grant GM_setValue
// @grant GM_getValue
// ==/UserScript==
// Storing a setting across sessions
GM_setValue('userTheme', 'dark');
// Retrieving the setting with a default fallback
const theme = GM_getValue('userTheme', 'light');
console.log(`Current theme: ${theme}`);If @grant none is set, the script runs directly in the
page’s context and loses access to GM_setValue, forcing
reliance on localStorage or IndexedDB.
Best Practices for Userscript Storage
- Use GM Functions for Cross-Domain Scripts: If your
script runs on multiple domains, use
GM_setValueto ensure settings carry over everywhere. - Serialize Complex Objects: While modern GM APIs
handle JSON objects natively, explicitly serializing complex objects
using
JSON.stringify()andJSON.parse()ensures compatibility across older script managers. - Protect Sensitive Credentials: Avoid storing unencrypted passwords or sensitive personal data in standard web storage, as host page scripts can inspect local storage objects.