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.
The CDN import sample is the one that made this click for me. Once you can pull an arbitrary ESM module at runtime, the extension stops being a snippet runner and becomes a tiny scripting environment sitting on top of whatever page the user is on. That's a genuinely different product than "custom context menu."
Which leads to the thing I'd think hardest about: your distribution model is people sharing scripts. The watermark sample is already 100+ lines with a proxyFetch that bypasses CORS. Most users will not read that before running it, they'll paste it because it does something they want. That's a great growth loop and a real liability in the same mechanism.
Worth deciding early whether you want to own that. A few options that don't kill the magic: show a diff of what permissions a script actually touches before first run, or keep a curated set that you've reviewed separately from arbitrary pasted code so there's a visible trust boundary between "official" and "from a forum."
Also practical: how are you handling the Chrome Web Store review? Remote code execution is one of the specific things their policy calls out, and I'd be curious whether the CDN import survived review or whether you had to frame it a particular way.
proxyFetch is the interesting compromise here: you traded null-origin CORS pain for an explicit host-permission prompt, which is the right direction, but it means the threat model is now "whatever the user pasted" plus "whatever the allowlisted CDNs happen to serve today". That second half is worth hardening before it becomes a Web Store conversation, because importing code from jsDelivr or unpkg at run time sits uncomfortably close to the remotely-hosted-code rule reviewers apply under MV3 — pinning exact versions with an integrity hash instead of latest shrinks the supply-chain surface and gives you a much cleaner answer if review ever asks. On adoption, the bigger constraint is that most people who want a right-click to actually do something won't write the five lines themselves, so a small built-in catalogue of ready-made items (resize an image, copy selection as markdown, look up a highlighted SKU) turns install day into value day and makes the script writers your contributors rather than your whole market. I'd also treat an edit as a new grant: a menu item that quietly acquires a new host after approval is exactly how tools like this lose trust, and re-prompting on capability change is cheap insurance. Are you planning a way for people to share scripts, and if so would you review submissions yourself or rely on per-script permission diffs to keep that safe as volume grows?
The engineering here is the easy part to admire and the hard part to sell, because the group who can write the snippet is much smaller than the group who wants the outcome. The unlock is probably a shared library of ready-made menu items, so people install a script rather than write one and the authors become your distribution. I watched this exact thing in the Microsoft world with PowerShell, where the durable value moved from the runtime to the gallery of scripts people could grab without fully understanding them.
Running dynamic JS directly from the context menu is super useful for quick automations and dev shortcuts. How are you handling CSP (Content Security Policy) restrictions across stricter websites? Neat project!
Awesome project! Being able to trigger custom JavaScript directly from the context menu opens up so many possibilities for quick automation and productivity hacks. As a tech enthusiast studying web development at Universitas Airlangga, seeing creative browser extensions like this is super inspiring for our own side projects. Thanks for sharing this!
One thing worth flagging alongside the per-script capability summary suggestion below: host permissions and script content can drift apart after the fact. If I grant api.github.com for one script today, then edit that same menu item's code next week to also hit a different host or do something riskier, does the extension re-prompt, or does editing silently inherit whatever was already granted?
That gap matters more here than in a typical extension because the "install once, review once" model assumes the code doesn't change after you've vetted it — but the whole pitch of Menu Mod is that editing scripts is the normal workflow, not a rare event. A capability summary at save-time (not just install-time) seems like it'd close that, otherwise the permission grant becomes stale the moment someone tweaks their own script.
“This is a really interesting approach. I especially like the idea of turning the context menu into a real execution layer instead of just another shortcut system. Curious how you handled permissions and security around arbitrary JavaScript execution.”
The scripting part is what got me. I have a few repetitive things that a right-click menu could actually take care of, never thought of wiring them that way. Bookmarking this to try on Monday.
That’s a clear wedge. I’d be nervous about permissions and “this extension can read all sites.” If the landing leads with one boring use case (rename a file, strip a param) instead of “run any JS,” more people will try it.
This is a perfect example of constraints forcing clarity. You started with a question: "what if I could make a right-click menu do something real?" That constraint - the specific UI surface - eliminated a thousand wrong directions. You couldn't confuse this with a general automation tool or a full scripting platform because the right-click menu IS the answer.
Founders often see constraints as limiting, but the clarity they buy is worth more than the breadth you give up. People who want this know exactly what they're buying. No ambiguity about scope.
The moat here is not the runtime, it is the script library, because most people who want this outcome cannot write the snippet themselves. I would ship 20 prebuilt menu items for real jobs (check this SKU price, push this selection to a CRM, run this text through an API) so a non-scripter gets value on install day. That also turns users into your content engine, because every good script someone writes becomes a distribution asset you can publish.
The individual utility is clear, but the team version may be the stronger paid wedge: approved script templates, version history, permission review, an execution log, and an admin-managed allowlist. I would test one shared workflow where five people repeat the same browser action, such as enriching a support ticket or checking an internal record. If the team installs and maintains one script centrally, you are no longer selling convenience to one developer; you are selling a controlled automation layer.
This could be surprisingly powerful for small repetitive tasks. I can imagine using it for formatting text, grabbing page data or automating little workflows without opening DevTools every time. Are there any limits on what the scripts can access?
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.
Thank you for the kind words.
I skipped adding a shareable scripts workflow for now due to the exact issues you mentioned.
It is on the roadmap but I will need to carefully implement this while avoiding/minimizing potential security issues.
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?
A heartbeat ping keeps the Service Worker alive for the duration of the task.
The extension uses a single Offscreen document host.
Every script execution creates a brand new, isolated Web Worker in the Offscreen document. The user script code runs entirely within this dedicated Web Worker thread.
Scripts run concurrently in parallel; they do not queue, share worker state or clobber each other.
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
The proxyFetch + OffscreenCanvas work is clever, you've made the right-click menu a scripting surface nobody's built. But the sharp thing isn't technical, it's who this is for: what makes it powerful caps who adopts it.
"Same rule you'd apply to anything you paste into a console" is the tell: this is a power tool for people who think in JS snippets. A real, underserved audience (devs automating browser tasks) but narrow. Marketing it as a general "custom right-click menu" pulls in people who bounce the moment they see code. Lean INTO the dev framing: "bind a JS snippet to a right-click" self-selects who'll use it.
The moat is the ceiling: it's for people who can write the script. Growth becomes "where do those devs gather."
Most common script your users bind so far?