# oss-invisible/playwright architecture

> Architecture diagram of the GitHub repository oss-invisible/playwright, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-11-15). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/oss-invisible/playwright
- Repository: https://github.com/oss-invisible/playwright

## Overview

invisible_playwright wraps Playwright’s sync and async APIs around a patched Firefox engine. A user creates a seeded or randomized session, the package resolves and validates the engine, and Playwright commands travel through its Juggler protocol to Firefox; humanized pointer input and engine-level fingerprinting shape browser behavior. The README also documents verified engine fetching, proxies/timezone handling, and a WebSocket server for remote clients. Edges reflect README statements and shown source references; unsampled implementation details are not asserted.

Main entry points: [`src/invisible_playwright/launcher.py`](https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/launcher.py) (Browser Launcher), [`src/invisible_playwright/_engine.py`](https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/_engine.py) (Engine Resolver), [`src/invisible_playwright/_juggler/transport.py`](https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/_juggler/transport.py) (Protocol Transport), [`src/invisible_playwright/__init__.py`](https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/__init__.py) (InvisiblePlaywright)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_entry["Public API"]
  node_public["InvisiblePlaywright<br/>[__init__.py]"]
  node_sync["Sync API"]
  node_async["Async API"]
end

subgraph group_runtime["Session Runtime"]
  node_launcher["Browser Launcher<br/>[launcher.py]"]
  node_session["Session Setup<br/>[_session.py]"]
  node_engine["Engine Resolver<br/>[_engine.py]"]
end

subgraph group_protocol["Playwright Protocol"]
  node_connection["Protocol Connection<br/>[_connection.py]"]
  node_context["Browser Context"]
  node_page["Page Automation<br/>[_page.py]"]
  node_frame["Frame Automation<br/>[_frame.py]"]
  node_api_types["API Data Types<br/>[_api_structures.py]"]
  node_dispatcher["Juggler Dispatcher<br/>[dispatcher.py]"]
  node_juggler["Juggler Server<br/>[server.py]"]
  node_transport["Protocol Transport<br/>[transport.py]"]
end

subgraph group_stealth["Fingerprint and Input"]
  node_fingerprint["Engine Fingerprint<br/>[_engine.py]"]
  node_geo["Geo and Timezone<br/>[_geo.py]"]
  node_cursor["Humanized Cursor<br/>[_cursor.py]"]
  node_pointer["Pointer Actions<br/>[pointer.py]"]
end

subgraph group_remote["Remote Browser"]
  node_remote_api["Remote Server API<br/>[remote.py]"]
end

node_user(("Automation User"))
node_firefox["Patched Firefox"]
node_remote_client(("Playwright Client"))

node_user -->|"creates session"| node_public
node_user -->|"uses sync"| node_sync
node_user -->|"uses async"| node_async
node_public -->|"launches"| node_launcher
node_public -->|"resolves engine"| node_engine
node_public -->|"exports server"| node_remote_api
node_sync -->|"creates connection"| node_connection
node_sync -->|"uses transport"| node_transport
node_async -->|"creates connection"| node_connection
node_async -->|"uses transport"| node_transport
node_launcher -->|"starts session"| node_session
node_launcher -->|"configures input"| node_cursor
node_launcher -->|"resolves binary"| node_engine
node_session -->|"validates engine"| node_engine
node_session -->|"starts protocol"| node_juggler
node_session -->|"uses cursor"| node_cursor
node_engine -->|"selects binary"| node_firefox
node_engine -->|"checks seal"| node_fingerprint
node_connection -->|"sends messages"| node_transport
node_connection -->|"dispatches objects"| node_context
node_context -->|"creates pages"| node_page
node_page -->|"delegates actions"| node_frame
node_page -->|"uses types"| node_api_types
node_dispatcher -->|"dispatches actions"| node_pointer
node_pointer -->|"uses motion"| node_cursor
node_transport -->|"carries protocol"| node_juggler
node_juggler -->|"controls browser"| node_firefox
node_remote_api -->|"starts browser"| node_launcher
node_remote_client -->|"connects by WebSocket"| node_remote_api
node_remote_api -->|"serves protocol"| node_transport
node_user -->|"sets timezone"| node_geo

click node_public "https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/__init__.py"
click node_sync "https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/_pw/sync_api/_context_manager.py"
click node_async "https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/_pw/async_api/_context_manager.py"
click node_launcher "https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/launcher.py"
click node_session "https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/_session.py"
click node_engine "https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/_engine.py"
click node_connection "https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/_pw/_impl/_connection.py"
click node_context "https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/_pw/_impl/_browser_context.py"
click node_page "https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/_pw/_impl/_page.py"
click node_frame "https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/_pw/_impl/_frame.py"
click node_api_types "https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/_pw/_impl/_api_structures.py"
click node_dispatcher "https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/_juggler/dispatcher.py"
click node_juggler "https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/_juggler/server.py"
click node_transport "https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/_juggler/transport.py"
click node_fingerprint "https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/_engine.py"
click node_geo "https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/_geo.py"
click node_cursor "https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/_cursor.py"
click node_pointer "https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/_juggler/pointer.py"
click node_remote_api "https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/_juggler/remote.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_public,node_sync,node_async,node_user,node_remote_client toneBlue
class node_launcher,node_session,node_engine toneAmber
class node_connection,node_context,node_page,node_frame,node_api_types,node_dispatcher,node_juggler,node_transport toneMint
class node_fingerprint,node_geo,node_cursor,node_pointer toneRose
class node_remote_api,node_firefox toneIndigo
```

## Components

### Public API

- [InvisiblePlaywright](https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/__init__.py): `src/invisible_playwright/__init__.py`
- [Sync API](https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/_pw/sync_api/_context_manager.py): `src/invisible_playwright/_pw/sync_api/_context_manager.py`
- [Async API](https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/_pw/async_api/_context_manager.py): `src/invisible_playwright/_pw/async_api/_context_manager.py`

### Session Runtime

- [Browser Launcher](https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/launcher.py): `src/invisible_playwright/launcher.py`
- [Session Setup](https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/_session.py): `src/invisible_playwright/_session.py`
- [Engine Resolver](https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/_engine.py): `src/invisible_playwright/_engine.py`

### Playwright Protocol

- [Protocol Connection](https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/_pw/_impl/_connection.py): `src/invisible_playwright/_pw/_impl/_connection.py`
- [Browser Context](https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/_pw/_impl/_browser_context.py): `src/invisible_playwright/_pw/_impl/_browser_context.py`
- [Page Automation](https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/_pw/_impl/_page.py): `src/invisible_playwright/_pw/_impl/_page.py`
- [Frame Automation](https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/_pw/_impl/_frame.py): `src/invisible_playwright/_pw/_impl/_frame.py`
- [API Data Types](https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/_pw/_impl/_api_structures.py): `src/invisible_playwright/_pw/_impl/_api_structures.py`
- [Juggler Dispatcher](https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/_juggler/dispatcher.py): `src/invisible_playwright/_juggler/dispatcher.py`
- [Juggler Server](https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/_juggler/server.py): `src/invisible_playwright/_juggler/server.py`
- [Protocol Transport](https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/_juggler/transport.py): `src/invisible_playwright/_juggler/transport.py`

### Fingerprint and Input

- [Engine Fingerprint](https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/_engine.py): `src/invisible_playwright/_engine.py`
- [Geo and Timezone](https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/_geo.py): `src/invisible_playwright/_geo.py`
- [Humanized Cursor](https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/_cursor.py): `src/invisible_playwright/_cursor.py`
- [Pointer Actions](https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/_juggler/pointer.py): `src/invisible_playwright/_juggler/pointer.py`

### Remote Browser

- [Remote Server API](https://github.com/oss-invisible/playwright/blob/main/src/invisible_playwright/_juggler/remote.py): `src/invisible_playwright/_juggler/remote.py`

### Other components

- **Automation User**
- **Patched Firefox**
- **Playwright Client**

## Connections

- Automation User → InvisiblePlaywright: creates session (evidence: `README.md`)
- Automation User → Sync API: uses sync (evidence: `README.md`)
- Automation User → Async API: uses async (evidence: `README.md`)
- InvisiblePlaywright → Browser Launcher: launches (evidence: `src/invisible_playwright/__init__.py`)
- InvisiblePlaywright → Engine Resolver: resolves engine (evidence: `src/invisible_playwright/__init__.py`)
- InvisiblePlaywright → Remote Server API: exports server (evidence: `src/invisible_playwright/__init__.py`)
- Sync API → Protocol Connection: creates connection (evidence: `src/invisible_playwright/_pw/sync_api/_context_manager.py`)
- Sync API → Protocol Transport: uses transport (evidence: `src/invisible_playwright/_pw/sync_api/_context_manager.py`)
- Async API → Protocol Connection: creates connection (evidence: `src/invisible_playwright/_pw/async_api/_context_manager.py`)
- Async API → Protocol Transport: uses transport (evidence: `src/invisible_playwright/_pw/async_api/_context_manager.py`)
- Browser Launcher → Session Setup: starts session (evidence: `src/invisible_playwright/launcher.py`)
- Browser Launcher → Humanized Cursor: configures input (evidence: `src/invisible_playwright/launcher.py`)
- Browser Launcher → Engine Resolver: resolves binary (evidence: `src/invisible_playwright/launcher.py`)
- Session Setup → Engine Resolver: validates engine (evidence: `src/invisible_playwright/_session.py`)
- Session Setup → Juggler Server: starts protocol (evidence: `src/invisible_playwright/_session.py`)
- Session Setup → Humanized Cursor: uses cursor (evidence: `src/invisible_playwright/_session.py`)
- Engine Resolver → Patched Firefox: selects binary (evidence: `src/invisible_playwright/_engine.py`)
- Engine Resolver → Engine Fingerprint: checks seal (evidence: `src/invisible_playwright/_engine.py`)
- Protocol Connection → Protocol Transport: sends messages (evidence: `src/invisible_playwright/_pw/_impl/_connection.py`)
- Protocol Connection → Browser Context: dispatches objects (evidence: `src/invisible_playwright/_pw/_impl/_connection.py`)
- Browser Context → Page Automation: creates pages (evidence: `src/invisible_playwright/_pw/_impl/_browser_context.py`)
- Page Automation → Frame Automation: delegates actions (evidence: `src/invisible_playwright/_pw/_impl/_page.py`)
- Page Automation → API Data Types: uses types (evidence: `src/invisible_playwright/_pw/_impl/_page.py`)
- Juggler Dispatcher → Pointer Actions: dispatches actions (evidence: `src/invisible_playwright/_juggler/dispatcher.py`)
- Pointer Actions → Humanized Cursor: uses motion (evidence: `src/invisible_playwright/_juggler/pointer.py`)
- Protocol Transport → Juggler Server: carries protocol (evidence: `src/invisible_playwright/_juggler/transport.py`)
- Juggler Server → Patched Firefox: controls browser (evidence: `README.md`)
- Remote Server API → Browser Launcher: starts browser (evidence: `src/invisible_playwright/_juggler/remote.py`)
- Playwright Client → Remote Server API: connects by WebSocket (evidence: `README.md`)
- Remote Server API → Protocol Transport: serves protocol (evidence: `src/invisible_playwright/_juggler/remote.py`)
- Automation User → Geo and Timezone: sets timezone (evidence: `README.md`)
