I'm the dev behind Menu Mod, a Chrome extension for building custom right-click menus. If you've ever wanted a right click to actually do something (hit an API, check a price, kick off a small automation) instead of just opening a search URL, that's what this is.
Scripting support just shipped in v2.
TLDR: Each menu item can run a full JS snippet in a sandboxed Web Worker, triggered by a single right click, with a 5 minute execution budget and a 30 MB cap on whatever the script returns. So instead of writing a whole extension for one small repetitive task, you write one script and bind it to a menu item.
Manifest v3 introduced a lot of 'interesting' constraints around user defined code that I have worked hard to address:
1. CORS limitations in the worker, and a proxy around it
The sandbox runs on a null origin, so a plain fetch() inside a script hits normal CORS rules and gets blocked by anything that doesn't explicitly allow null.
To fix this, I added proxyFetch(). proxyFetch routes the request through the extension's own origin instead, which sidesteps that. It requires the user to grant a host permission first through a URL pattern in settings, Chrome prompts for approval and any host that hasn't been explicitly permitted just fails with a clear error.
In practice, this means your script can talk to basically any internal tool or third party API you actually use instead of just APIs with permissive CORS.
2. No DOM but graphics manipulation still works
Workers don't get a DOM, so no document.createElement, no Image(), no HTML or XML parsing. What they do get is OffscreenCanvas for actual 2D rendering, path drawing and pixel manipulation, plus createImageBitmap for hardware accelerated image decoding. FileReaderSync is also available, so a script can read a Blob into base64.
That means things like resizing an image, drawing a watermark or generating a quick thumbnail on right click are doable without opening any other tool.
3. Post Script Actions
A script can return a plain string for a quick notification, or one or more command objects that run after the script finishes: open a URL, copy to clipboard, download a file, show a notification or chain several of those together.
Example, a script that pulls repo info on right click:
const repo = context.selection?.trim()
const data = await fetch(`https://api.github.com/repos/${repo}`).then(res => res.json())
return [
{
action: 'showNotification',
payload: { title: data.full_name, text: `${data.stargazers_count} stars, ${data.open_issues_count} open issues` }
},
{
action: 'copyToClipboard',
payload: { text: data.clone_url }
},
{
action: 'openUrl',
payload: { url: data.html_url }
}
]
Highlight a repo name like react/react, right click, get a notification with stars and open issues, the clone URL copied to your clipboard and the repo page opened, all from one script tied to one menu item.
Are there any risks?
No DOM access and no direct chrome.* API access means a script can't reach into the page you right-clicked on or touch extension internals directly. It can still make network requests, import code from an allowlisted set of CDNs (jsDelivr, unpkg, esm.sh and a few others) and send data somewhere.
Basically, the same rule you'd apply to anything you paste into a browser console.
If there's a repetitive right-click-then-alt-tab thing you do every day, this is probably a five line script away from being one click/shortcut.
Quick demo - https://www.youtube.com/watch?v=GQtmLrb1fF4
Chrome Web Store - https://chromewebstore.google.com/detail/menu-mod-right-click-menu/hidbgnneihkhinffhjbkkdacpgmdlcgj
Still actively building this, so if you run into rough edges or have some ideas, I'm listening.
This sounds like one of those tools where the use cases only become obvious after people start using it. Being able to attach small JavaScript actions directly to the context menu could remove a lot of repetitive browser tasks. Do users create the scripts themselves, or are you planning some kind of shared library too?
This sounds like one of those tools where the use cases only become obvious after people start using it. Being able to attach small JavaScript actions directly to the context menu could remove a lot of repetitive browser tasks. Do users create the scripts themselves, or are you planning some kind of shared library too?
Nice approach, and the sandboxed-Worker choice is a smart way to stay MV3-compliant: user-authored scripts run from a local Blob instead of remote code, so you sidestep the "no remotely-hosted code" rule that kills a lot of extension ideas.
The one thing I'd poke at: a Web Worker has no DOM access and can't see the current page's JS context. So "hit an API" works great (fetch is happy in a worker), but "check a price" - if that means reading the price off the page you're actually looking at - can't work from the worker alone. You'd need a content script to scrape the DOM and message-pass the value in. Might be worth being explicit about that split, because people will assume a right-click script can read the page it was clicked on, and the sandbox is exactly why it can't.
Second thing, more caution than critique: the moment scripts become shareable, you inherit the userscript ecosystem's supply-chain problem - someone pastes a snippet from a forum that quietly fetch()es their session cookies out. Even inside the Worker sandbox, fetch plus whatever host permissions you've granted is enough to exfiltrate. If you ever add an import/share flow, a permission preview ("this script will talk to these domains") would go a long way.
Cool project though - the 5-min budget and return cap show you've already thought about runaways.
Being able to handle image tweaks or quick API lookups right from the context menu via OffscreenCanvas is brilliant. I can think of three annoying micro-tasks I do every day—like fetching quick stats or reformatting selected text—where I usually alt-tab to a terminal or web app. Replacing all that with a 5-line right-click script is huge.
Nice work on the MV3 wrangling. One thing I'd want spelled out in the docs: where does that 5 minute worker actually live? The service worker gets torn down after 30 seconds idle, and Chrome only lets an extension keep one offscreen document open at a time, so if that's the host then two long scripts fired back to back are sharing it. Does the second one queue, get its own worker inside the same document, or clobber the first?
The MV3 constraint work is actually the moat here — most developers who wanted this gave up when Manifest v3 closed the easy path. The fact that you've solved the CORS proxy, the null-origin worker isolation, and the storage cap means this isn't a weekend project that breaks in three months. That's worth communicating clearly in the positioning.
The distribution question I'd be thinking about: the person who knows they want "a right-click that hits an API" is a developer who could build their own extension. The person who'd pay for this without knowing the technical framing is the ops or power user who just knows they do the same five things every day and wants a shortcut.
Those two audiences need completely different onboarding — one wants the script editor open by default, the other wants a working script library they can deploy with one click without ever seeing code.
Which of those two actually shows up first when someone installs it today?
The five-minute worker budget is what makes this more than a fancy search menu. Before adding more actions, I'd build a dry-run view. It could show the selected text, hosts contacted, and commands that would run, without actually running anything. That would make copied scripts easier to inspect and debug, especially when a chain ends by copying to the clipboard, downloading something, or opening a URL. A one-click test run with sample context could also save you a pile of support tickets.
The ability to turn a right-click into an actual script execution is a pretty interesting upgrade from the usual custom menu extensions. Curious what people end up using scripting for first.
The per-host permission gate feels like the right primitive here. One thing I'd consider is making permissions visible per script, not just globally: a small capability summary (reads selected text, contacts api.github.com, copies to clipboard, opens a URL) before saving or running would make shared snippets much easier to trust. Are host grants currently scoped to the whole extension or to each menu item?
Thanks for the feedback.
Host grants are currently scoped to the whole extension, not per menu item.
The per-script capability summary is a great suggestion. I have added it to the roadmap.
A few more scripting samples
1: CDN import
2: One click image watermarker