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.

Key Limitation: Web Storage APIs are bound by the Same-Origin Policy. Data stored on example.com via localStorage cannot be accessed when the script runs on another-domain.com. Additionally, domain scripts can potentially access or modify data stored in localStorage.

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.


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