Skip to content

mrshappy0/open-monkey

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

8 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ’ OpenMonkey

The userscript manager that's actually yours.

OpenMonkey is a lightweight, open-source browser extension for running userscripts β€” built for people who are done handing their data to closed-source tools.


The Origin Story

Tampermonkey β€” the standard for years. Closed source. Ships your data wherever it wants. You have no idea what it's doing in the background.

ViolentMonkey β€” open source, which is great. But there's still telemetry and data collection in the mix. "Open source" doesn't automatically mean "private."

OpenMonkey β€” built from scratch, owned by you, never uploaded to the Chrome Web Store, never phoning home. It lives on your disk, runs in your browser, and that's where it stays. No accounts. No analytics. No middleman.


What It Does

  • Run userscripts on any website matching @match patterns
  • Full Greasemonkey/Tampermonkey-compatible script header format (@name, @match, @exclude, @run-at, @description, @version)
  • @run-at document-start / document-end / document-idle β€” proper lifecycle hooks
  • @exclude pattern support
  • Per-script @max-retries β€” built-in retry guard via sessionStorage to prevent infinite login loops or lockouts
  • Global default retry setting in the popup
  • Enable / disable scripts per-script
  • Full in-browser script editor (no external tools needed)
  • Zero network requests. All storage is chrome.storage.local β€” never synced, never sent anywhere.

Installation (Load Unpacked)

OpenMonkey is intentionally not on the Chrome Web Store. That's the point.

# 1. Clone the repo
git clone https://github.com/your-username/open-monkey.git
cd open-monkey

# 2. Install dependencies
pnpm install

# 3. Build
pnpm build

# 4. Load into Chrome
# Open chrome://extensions β†’ Enable "Developer mode" β†’ "Load unpacked" β†’ select .output/chrome-mv3/

For live development with hot-reload:

pnpm dev

WXT will automatically open Chrome with the extension loaded. Changes to any entrypoint or utility file rebuild and reload instantly.


Project Structure

OpenMonkey is built on WXT β€” the modern framework for browser extensions. It follows WXT's strict project layout conventions.

open-monkey/
β”œβ”€β”€ entrypoints/
β”‚   β”œβ”€β”€ background.ts          # MV3 service worker β€” matches tabs β†’ injects scripts
β”‚   └── popup/
β”‚       β”œβ”€β”€ index.html         # Popup HTML shell
β”‚       β”œβ”€β”€ main.tsx           # React root mount
β”‚       β”œβ”€β”€ App.tsx            # Script list + editor UI
β”‚       β”œβ”€β”€ App.css            # Popup styles
β”‚       └── style.css          # Global reset/base
β”œβ”€β”€ utils/
β”‚   β”œβ”€β”€ storage.ts             # Typed WXT storage items (scripts + settings)
β”‚   β”œβ”€β”€ meta-parser.ts         # Parses ==UserScript== header blocks
β”‚   β”œβ”€β”€ match-pattern.ts       # Chrome match-pattern URL matching
β”‚   └── logger.ts              # Dev-mode logger wrapper
β”œβ”€β”€ assets/                    # Processed assets (imported in code)
β”œβ”€β”€ public/
β”‚   └── icon/                  # Extension icons (copied as-is to output)
β”œβ”€β”€ wxt.config.ts              # WXT config β€” manifest options, modules
β”œβ”€β”€ web-ext.config.ts          # Browser launch/dev config
β”œβ”€β”€ tsconfig.json              # TypeScript config (generated by WXT)
└── package.json

WXT Conventions Used

Convention What it means here
entrypoints/background.ts Auto-registered as the MV3 service worker
entrypoints/popup/ Popup entrypoint directory β€” index.html is the root
utils/ Auto-imported by WXT β€” no import statements needed in most files
public/ Static files copied verbatim to .output/
assets/ Processed by Vite β€” use for imported images, fonts, etc.
defineBackground() WXT's entrypoint wrapper β€” keeps runtime code out of module scope
storage.defineItem() @wxt-dev/storage typed, versioned storage items
browser.* WXT's unified cross-browser API β€” works on Chrome and Firefox
pnpm build β†’ .output/chrome-mv3/ Standard WXT output directory

Userscript Format

OpenMonkey uses the standard Greasemonkey header format. Add scripts directly in the popup editor:

// ==UserScript==
// @name        My Script
// @description Brief description of what it does
// @version     1.0.0
// @match       https://example.com/*
// @exclude     https://example.com/login
// @run-at      document-end
// @max-retries 3
// ==/UserScript==

(function () {
  'use strict';

  // Your code here
})();

Supported Directives

Directive Description
@name Script display name (required)
@description Short description shown in the popup
@version Semver version string
@match URL pattern(s) to run on β€” supports Chrome match pattern syntax
@exclude URL pattern(s) to explicitly skip
@run-at document-start, document-end (default), or document-idle
@max-retries Max injection attempts per tab session (overrides global setting)

Multiple @match and @exclude lines are supported.


How Script Injection Works

The background.ts service worker listens to browser.tabs.onUpdated. On each navigation event:

  1. Load all scripts from chrome.storage.local
  2. Parse each script's ==UserScript== header
  3. Match the tab URL against @match / @exclude patterns
  4. Check @run-at against the current navigation phase (loading β†’ document-start, complete β†’ document-end)
  5. Wrap the script body in a sessionStorage-based retry guard (if maxRetries > 0)
  6. Inject via chrome.scripting.executeScript with world: "MAIN" β€” full DOM access, same context as page JS
// Scripts run in the page's own JS context, not the extension sandbox
await chrome.scripting.executeScript({
  target: { tabId },
  func: (code: string) => {
    const el = Object.assign(document.createElement('script'), { textContent: code });
    document.head.append(el);
    el.remove();
  },
  args: [codeToInject],
  world: 'MAIN',
});

This approach mirrors how Tampermonkey injects scripts and gives your userscripts the same DOM access they'd have in any other manager.


Storage

All data lives in chrome.storage.local. Nothing is ever synced or sent anywhere.

// Defined in utils/storage.ts using @wxt-dev/storage
export const scriptsItem = storage.defineItem<UserScript[]>('local:scripts', {
  fallback: [],
  version: 1,
});

export const settingsItem = storage.defineItem<Settings>('local:settings', {
  fallback: { maxRetries: 3 },
  version: 1,
});

@wxt-dev/storage handles typed reads/writes, reactive .watch() subscriptions (used by the popup's React state), and migration hooks for future schema changes.


Development

# Install deps
pnpm install

# Dev mode (Chrome, hot-reload)
pnpm dev

# Dev mode (Firefox)
pnpm dev:firefox

# Production build
pnpm build

# Production build for Firefox
pnpm build:firefox

# Zip for distribution (sideload/share)
pnpm zip

# TypeScript type check
pnpm compile

Philosophy

  • Never published to any store. Load unpacked, own it completely.
  • No telemetry, no analytics, no remote config. The extension makes zero outbound requests.
  • chrome.storage.local only. No sync storage. No IndexedDB. No server.
  • MV3 by default. Modern Manifest V3 with a proper service worker background.
  • Self-hosted and version-controlled. Fork it, modify it, make it yours.

Tech Stack

Tool Role
WXT Browser extension framework β€” build, dev, manifest generation
React 19 Popup UI
TypeScript Everywhere
@wxt-dev/storage Typed, versioned chrome.storage.local wrapper
pnpm Package manager
Vite Bundler (via WXT)

Roadmap

  • CodeMirror syntax highlighting in the editor
  • @require directive β€” load and cache external libraries
  • Per-script execution log / error display in popup
  • Import/export scripts as .user.js files
  • Options page for advanced settings
  • Firefox AMO sideload support (already builds with pnpm build:firefox)

License

MIT. Do whatever you want with it. That's also the point.

About

Lightweight, privacy-respecting userscript manager Chrome extension.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors