Skip to main content
This guide walks you through setting up Scramjet, a powerful web proxy framework that enables you to create isolated browsing contexts.

Prerequisites

Before you begin, ensure you have:
  • A web server capable of serving static files
  • Service worker support in your target browsers
  • The Scramjet distribution files (scramjet.all.js, scramjet.wasm.wasm, scramjet.sync.js)

Installation

1

Include Scramjet files

Place the Scramjet distribution files in your project directory. These files should be accessible via your web server:
/public/
  scramjet.all.js
  scramjet.wasm.wasm
  scramjet.sync.js
2

Register the service worker

Create a script to register Scramjet’s service worker. This is essential for intercepting and proxying requests:
// Register the service worker
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/sw.js', {
    scope: '/',
  }).then((registration) => {
    console.log('Scramjet service worker registered:', registration);
  }).catch((error) => {
    console.error('Service worker registration failed:', error);
  });
}
The service worker file (sw.js) should import Scramjet using importScripts('/scramjet.all.js') and set up the fetch handler. See the quickstart guide for a complete service worker example.
The scope parameter defines the URL prefix that the service worker will intercept. By default, Scramjet uses /scramjet/.
3

Initialize the controller

After the service worker is registered and ready, load and initialize the Scramjet controller:
// Wait for service worker to be ready
await navigator.serviceWorker.ready;

// Load the controller module
const { ScramjetController } = $scramjetLoadController();

// Create a controller instance with configuration
const scramjet = new ScramjetController({
  prefix: '/scramjet/',
  flags: {
    strictRewrites: true,
    captureErrors: true,
  },
});

// Initialize the controller
await scramjet.init();
4

Create and use a frame

Create an isolated iframe context for proxied browsing:
// Create a new Scramjet frame
const frame = scramjet.createFrame();

// Add the iframe to your page
document.body.appendChild(frame.frame);

// Navigate to a URL
frame.go('https://example.com');

Complete example

Here’s a full working example that ties everything together:
<!DOCTYPE html>
<html>
<head>
  <title>Scramjet Example</title>
  <style>
    iframe {
      width: 100%;
      height: 600px;
      border: 1px solid #ccc;
    }
  </style>
</head>
<body>
  <div id="controls">
    <input type="text" id="urlInput" placeholder="Enter URL" />
    <button id="goBtn">Go</button>
  </div>
  <div id="frameContainer"></div>

  <script>
    (async () => {
      // Step 1: Register service worker
      if ('serviceWorker' in navigator) {
        await navigator.serviceWorker.register('/scramjet.all.js', {
          scope: '/scramjet/',
        });
      }

      // Step 2: Wait for service worker to be ready
      await navigator.serviceWorker.ready;

      // Step 3: Initialize Scramjet controller
      const { ScramjetController } = $scramjetLoadController();
      const scramjet = new ScramjetController({
        prefix: '/scramjet/',
      });
      await scramjet.init();

      // Step 4: Create frame
      const frame = scramjet.createFrame();
      document.getElementById('frameContainer').appendChild(frame.frame);

      // Step 5: Set up navigation controls
      const urlInput = document.getElementById('urlInput');
      const goBtn = document.getElementById('goBtn');

      goBtn.addEventListener('click', () => {
        const url = urlInput.value;
        if (url) {
          frame.go(url);
        }
      });

      // Navigate on Enter key
      urlInput.addEventListener('keypress', (e) => {
        if (e.key === 'Enter') {
          goBtn.click();
        }
      });

      // Optional: Listen for URL changes
      frame.addEventListener('urlchange', (event) => {
        console.log('URL changed to:', event.url);
        urlInput.value = event.url;
      });
    })();
  </script>
</body>
</html>

Configuration options

The ScramjetController constructor accepts a configuration object with the following options:
The URL prefix for the proxy. Defaults to /scramjet/.
const scramjet = new ScramjetController({
  prefix: '/proxy/',
});
Feature flags that control Scramjet’s behavior. See Configuration flags for details.
const scramjet = new ScramjetController({
  flags: {
    strictRewrites: true,
    captureErrors: true,
    sourcemaps: true,
  },
});
Custom URL encoding/decoding functions. See Custom codecs for details.
const scramjet = new ScramjetController({
  codec: {
    encode: (url) => btoa(url),
    decode: (url) => atob(url),
  },
});
Paths to Scramjet distribution files.
const scramjet = new ScramjetController({
  files: {
    wasm: '/scramjet.wasm.wasm',
    all: '/scramjet.all.js',
    sync: '/scramjet.sync.js',
  },
});

Next steps

Working with frames

Learn how to create and manage isolated browsing contexts

Event handling

Handle navigation and download events

Configuration flags

Customize Scramjet’s behavior with feature flags

Custom codecs

Implement custom URL encoding strategies

Build docs developers (and LLMs) love