# scramjet: an interception based web proxy that runs in the page

> Scramjet is an experimental web proxy that evades internet censorship by intercepting and rewriting pages rather than routing traffic through a server, which lets it sandbox arbitrary web content, work around CORS restrictions and let you instrument a site from inside the browser. It is a TypeScript and Rust project with a rewriter compiled to WebAssembly, and the readme calls it experimental.

**MercuryWorkshop/scramjet** — Scramjet is a versatile web proxy designed to bypass internet censorship.

- Repository: https://github.com/MercuryWorkshop/scramjet
- Website: https://scramjet.mercurywork.shop/
- Stars: 582 · Forks: 1,179
- Language: TypeScript
- License: not declared
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/mercuryworkshop-scramjet

## The proxy runs inside the page rather than beside it

Scramjet is described as an experimental interception based web proxy designed to evade internet censorship and bypass arbitrary browser restrictions.

The mechanism is the interesting part, and it is what separates this from a conventional proxy. A typical proxy sits between you and a site, relays the traffic, and has to be hosted somewhere. Scramjet intercepts and rewrites, sandboxing arbitrary web content, bypassing CORS restrictions on loading websites, and instrumenting and debugging websites inside the browser itself. The readme points to a technical write-up about how the web was ported to the web for the details.

The list of supported sites is the practical part of the readme, and it is a list of what people actually want to reach: Google, Youtube, Instagram, ChatGPT, Reddit, Twitter, Discord, Spotify, GeForce NOW and now.gg. The presence of Discord and Twitter alongside the big names is a hint at the intended use, since those are the two services most often blocked on networks that censor.

The framing in the readme is careful. It says experimental, and it says designed to evade internet censorship and bypass arbitrary browser restrictions, and it points at the interception, rewriting and sandboxing techniques as the combination that does the work. There is no claim of being a full featured proxy server, and that is deliberate, because the whole point of running inside the page is that the browser does the fetching and the interception layer rewrites what comes back.

The project lives under the Mercury Workshop organisation, publishes to npm as @mercuryworkshop/scramjet, and has a homepage at scramjet.mercurywork.shop.

## The build is Rust, WebAssembly and a forked wasm-snip

The dependency list is short and tells you that this is a TypeScript project with a compiled Rust core.

You need recent versions of node.js and pnpm, plus rustup, wasm-bindgen, Binaryen's wasm-opt, and a specific wasm-snip fork. The fork is the part worth noting. Snippet is the tool that finds and extracts the JavaScript snippets embedded in a page, and upstream has not always handled the modern bundlers that a site like the ones supported here uses, so the project maintains its own version of it.

The build sequence is five steps, and the order matters because the rewriter is a separate artefact from the main package:

Clone the repository with `git clone --recursive https://github.com/MercuryWorkshop/scramjet`, install the dependencies with `pnpm i`, change directories with `cd packages/core`, build the rewriter with `pnpm rewriter:build`, and build Scramjet with `pnpm build`.

The recursive clone is required rather than decorative, since the wasm-snip fork and the other pieces are submodules.

The repository layout matches that split. There is a packages/ directory holding the workspace members, with packages/core being the one the build steps enter, a patches/ directory for the patched dependencies, a rspack.config.ts as the bundler configuration, devserver.ts and devlib.ts for the local development server, a tests/ directory, and codespace-basic-setup.sh for running the environment in a codespace. The workspace is a pnpm workspace, pinned to pnpm 10.12.1, and a preinstall script runs npx only-allow pnpm to enforce that choice rather than allowing npm or yarn.

## Running it locally means one command and a port

The local development story is short, and the readme says so plainly.

You can run the Scramjet dev server with a single command at the root:

```sh
pnpm dev
```

The demo page for scramjet should then be running at http://localhost:4141, and it should rebuild upon a file being changed, excluding the rewriter. That last clause is the important operational detail. The rewriter is the compiled WebAssembly piece, and rebuilding it is a separate step, so a change to the rewriter source does not hot reload. The fast loop applies to the TypeScript, and the compiled part is a deliberate build step.

The dev script itself is defined in the root package.json as running the devserver.ts file with node, with the experimental warning suppressed:

```json
		"dev": "node --no-warnings=ExperimentalWarning devserver.ts",
		"dev:debug": "DEBUG=1 node --no-warnings=ExperimentalWarning devserver.ts",
```

The debug variant sets a DEBUG environment variable and nothing else, which is the usual convention for turning on extra logging in a Node process. The suppression of the experimental warning is a sign of how much experimental surface the runtime touches, and the root package runs as an ES module with type set to module.

The testing setup is small. There is a single script, test:package, which runs an ava test file called packageValidation.js from the tests/ci directory, and the ava configuration in the manifest points at the tests/ci glob with verbose output. The devDependencies are built around rspack for the bundling, with the type checker and a doctor plugin for the build, plus fastify's deepmerge, vite, ava, glob, eslint, chalk and a chafa-wasm package, the last being a terminal image renderer that is presumably used to preview the sandboxed content in the terminal.

## An experimental project with a continuous build channel

The release history says what to expect from a project in this state.

The three most recent tags are latest, labelled Continuous Build, from 2026-07-30, v2.0.67-alpha.2 from 2026-06-24 and v2.0.67-alpha.1 from 2026-05-24. A tag called latest that is a continuous build tells you the project does not cut numbered releases in the usual way, and the two alpha tags in the 2.0.67 line tell you the 2.x line has been in alpha for a while.

The repository is not archived, the default branch is main, and the last push was on 2026-09-24, about four weeks before the current date. So the work is continuing.

The licence is the one thing to sort out before doing anything with this. The licence field is not classified, and the badge and the manifest tell a different story: the root package.json declares the licence as AGPL-3.0-only and the author as Mercury Workshop. AGPL with a network use clause is a significant obligation for a proxy, and a project whose headline capability is evading network restrictions is exactly the kind of code where the licence terms and the intended use deserve a careful read rather than an assumption.

The homepage is scramjet.mercurywork.shop, the npm package is @mercuryworkshop/scramjet, and the readme links the technical write-up for how the interception and rewriting work. For anyone evaluating this, the sensible order is to read the write-up, then the licence, then run the demo, because the demo is the fastest way to understand what the tool actually does on the sites you care about.

## Conclusion

scramjet suits a developer who needs to load or instrument a site that will not cooperate, and who is prepared to work with an explicitly experimental project whose own readme describes it as experimental and whose release channel is a continuous build rather than a version. It does not suit a production deployment, since there is no stable release line and the licence is recorded as unknown in the repository metadata even though the package manifest declares AGPL-3.0-only, so the terms need checking before distribution. Before building it, install the Rust toolchain, wasm-bindgen, wasm-opt and the wasm-snip fork, then run pnpm dev and open the demo on port 4141 to see what it handles before you point it at anything.

## FAQ

### What is Scramjet?

It is an experimental interception based web proxy designed to evade internet censorship and bypass arbitrary browser restrictions. It sandboxes arbitrary web content, bypasses CORS restrictions when loading websites, and lets you instrument and debug websites inside the browser itself, using a combination of interception, rewriting and sandboxing techniques.

### How do I build Scramjet from source?

You need node.js and pnpm, rustup, wasm-bindgen, Binaryen's wasm-opt and the project's wasm-snip fork. Then clone recursively with git clone --recursive https://github.com/MercuryWorkshop/scramjet, run pnpm i, cd packages/core, run pnpm rewriter:build and finally pnpm build.

### How do I run Scramjet locally?

Run pnpm dev at the root of the repository. The demo page is then served at http://localhost:4141, and it rebuilds automatically when a file changes, except the rewriter, which is compiled separately by the pnpm rewriter:build step.

### Which websites does Scramjet support?

The readme lists Google, Youtube, Instagram, ChatGPT, Reddit, Twitter, Discord, Spotify, GeForce NOW and now.gg among the popular sites it supports. The project links a technical write-up about how the interception and rewriting techniques work.

## Sources

- [Issues](https://github.com/MercuryWorkshop/scramjet/issues)
- [MercuryWorkshop/scramjet on GitHub](https://github.com/MercuryWorkshop/scramjet)
- [Project website](https://scramjet.mercurywork.shop/)
- [README](https://github.com/MercuryWorkshop/scramjet/blob/main/README.md)
- [Releases](https://github.com/MercuryWorkshop/scramjet/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/mercuryworkshop-scramjet
