Self-hosted remote browser isolation. Chromium runs on your server and each page is rebuilt as a scriptless, interactive DOM in your browser, so text stays real selectable text while scripts, cookies and sessions stay remote.
  • TypeScript 94.5%
  • JavaScript 3.9%
  • CSS 0.8%
  • Shell 0.8%
Find a file
2026-08-26 00:03:53 +03:00
.github Public portfolio release 2026-08-25 23:48:20 +03:00
assets Public portfolio release 2026-08-25 23:48:20 +03:00
deploy Preserve executable script modes 2026-08-26 00:03:53 +03:00
docs Public portfolio release 2026-08-25 23:48:20 +03:00
packages Public portfolio release 2026-08-25 23:48:20 +03:00
scripts Preserve executable script modes 2026-08-26 00:03:53 +03:00
.dockerignore Public portfolio release 2026-08-25 23:48:20 +03:00
.env.example Public portfolio release 2026-08-25 23:48:20 +03:00
.gitignore Public portfolio release 2026-08-25 23:48:20 +03:00
.node-version Public portfolio release 2026-08-25 23:48:20 +03:00
.nvmrc Public portfolio release 2026-08-25 23:48:20 +03:00
.prettierignore Public portfolio release 2026-08-25 23:48:20 +03:00
.prettierrc.json Public portfolio release 2026-08-25 23:48:20 +03:00
CHANGELOG.md Public portfolio release 2026-08-25 23:48:20 +03:00
CODE_OF_CONDUCT.md Public portfolio release 2026-08-25 23:48:20 +03:00
compose.persistent.yml Public portfolio release 2026-08-25 23:48:20 +03:00
compose.yml Public portfolio release 2026-08-25 23:48:20 +03:00
CONTRIBUTING.md Public portfolio release 2026-08-25 23:48:20 +03:00
LICENSE Public portfolio release 2026-08-25 23:48:20 +03:00
NOTICE Public portfolio release 2026-08-25 23:48:20 +03:00
package.json Public portfolio release 2026-08-25 23:48:20 +03:00
pnpm-lock.yaml Public portfolio release 2026-08-25 23:48:20 +03:00
pnpm-workspace.yaml Public portfolio release 2026-08-25 23:48:20 +03:00
README.md Public portfolio release 2026-08-25 23:48:20 +03:00
SECURITY.md Public portfolio release 2026-08-25 23:48:20 +03:00
THIRD_PARTY_NOTICES.md Public portfolio release 2026-08-25 23:48:20 +03:00
tsconfig.base.json Public portfolio release 2026-08-25 23:48:20 +03:00

Remote Browser — the page stays on the server, the text stays text

Remote Browser runs a web page on your server and rebuilds it as a scriptless, interactive page in your browser.

Text stays sharp, selectable, copyable, and locally findable. Visited-page JavaScript, cookies, and network sessions stay inside the remote Chromium. When a page cannot be faithfully rebuilt, media lanes and a whole-tab pixel mode cover the difficult parts.

Quick start · How it works · Configuration · Deployment · Security

Important

This is an early build for a small set of trusted viewers. Its scriptless DOM mirror is a different security boundary from pixel-only remote browsing. Read the security model before exposing it beyond localhost.

Quick start

You need Docker Engine and Docker Compose v2 on a modern Linux host.

git clone https://github.com/mystxcal/remote-browser.git
cd remote-browser
./scripts/bootstrap.sh

The bootstrap creates local credentials, builds the two containers, waits for Chromium, and prints the URL and generated password. It leaves an existing .env untouched.

Open http://localhost:8080 and browse. The default deployment listens only on loopback and keeps the Chromium profile ephemeral.

docker compose ps
curl --fail http://localhost:8080/healthz

Stop it with:

docker compose down

Compared with

Most remote browsing hands you pixels. Remote Browser hands you a rebuilt page, so text is still text.

Compared with Why use Remote Browser Use the other tool when
Kasm Workspaces and other streamed-container browsers Text stays selectable, copyable, and findable with your browser's own search, and a page costs a DOM diff rather than a video stream. You need full desktop applications, or a hardened throwaway container per session.
Apache Guacamole Built for the one case of a web page instead of being a general RDP, VNC, and SSH gateway. You want remote desktops and shells through the same door.
Commercial remote browser isolation (Cloudflare, Zscaler) Self-hosted and inspectable, with the reconstruction rules in this repository. You need enterprise policy, identity integration, and a support contract.
A plain VNC or X session Much less bandwidth, and the page reflows to your window instead of arriving as a fixed-size screenshot. You want raw pixels for everything, rather than only where reconstruction gives up.

How it works

The page remains authoritative in remote Chromium. An in-page recorder sends a snapshot and ordered changes to the gateway, which rebuilds them inside a sandboxed viewer without running the visited page's scripts. Input travels back to the real page through Chrome DevTools Protocol events.

This is not VNC. Ordinary pages remain semantic, so text and interaction can stay local and crisp. Canvas, video, WebGL, and divergent pages can fall back to scoped WebRTC or pixels.

The current build includes:

  • Full interaction. Tabs, navigation, pointer, keyboard, touch, IME, uploads, and downloads.
  • Recovery in order. A viewer that falls behind resyncs without losing its place.
  • Real page structure. Shadow DOM, cross-origin frames, proxied assets, fonts, and CSS.
  • Driver and viewer roles for a small trusted group.
  • An optional persistent browser profile.

The default Compose path runs one browsing session. Compatibility still varies by site, especially around DRM, unusual browser APIs, hostile CSP combinations, and cross-origin media.

Read Architecture for the full data flow and Troubleshooting when a page diverges.

Deployment

Keep the application port on loopback and put HTTPS in front of it. CDP must remain private.

Three things to get right:

  • Use stable signing secrets. Rotating them invalidates every live session.
  • Install an outbound policy. Chromium must not reach your private infrastructure.
  • Leave profile persistence off unless you intend to retain browser credentials.

The exact settings and production boundary live in:

Development

Use Node 22.23.1 and pnpm 9.15.9.

corepack enable
pnpm install --frozen-lockfile
CHROME_PATH=/usr/bin/google-chrome pnpm run ci

pnpm run ci builds the workspace, checks types and formatting, runs the unit suite, and exercises the browser mirror against real Chromium.

See Contributing for the working rules.

Same idea, different job — one thing done properly, nothing in the middle, and a result you can check:

  • FrankenFile — self-hosted file drop; six characters, links expire
  • Chatinabox — drive the Codex CLI on your server from Telegram

The rest are listed on my profile.

License

Apache License 2.0. See LICENSE, NOTICE, and third-party notices.