{"id":51277637,"url":"https://github.com/ppietak/browserhut","last_synced_at":"2026-06-29T22:30:28.037Z","repository":{"id":340797171,"uuid":"1167472738","full_name":"ppietak/browserhut","owner":"ppietak","description":"A simple, self-hosted alternative to BrowserStack. (Currently macOS only)","archived":false,"fork":false,"pushed_at":"2026-02-26T14:42:26.000Z","size":79,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-26T20:38:23.760Z","etag":null,"topics":["android","docker","emulator","free","linux","macos","self-hosted","testing","web-development"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ppietak.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-26T10:31:19.000Z","updated_at":"2026-02-26T14:42:30.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ppietak/browserhut","commit_stats":null,"previous_names":["ppietak/browserhut"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/ppietak/browserhut","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ppietak%2Fbrowserhut","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ppietak%2Fbrowserhut/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ppietak%2Fbrowserhut/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ppietak%2Fbrowserhut/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ppietak","download_url":"https://codeload.github.com/ppietak/browserhut/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ppietak%2Fbrowserhut/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34945707,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-29T02:00:05.398Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","docker","emulator","free","linux","macos","self-hosted","testing","web-development"],"created_at":"2026-06-29T22:30:24.843Z","updated_at":"2026-06-29T22:30:28.017Z","avatar_url":"https://github.com/ppietak.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Browserhut\n\n[![Docker](https://img.shields.io/badge/Docker-required-2496ED?logo=docker\u0026logoColor=white)](https://www.docker.com)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)\n\n\u003e A simple, self-hosted alternative to BrowserStack.\n\u003e Run an Android emulator and a Linux Chromium desktop in your browser — no cloud, no subscriptions, everything on your machine.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"web/public/screenshot-dashboard.png\" height=\"240\" alt=\"Dashboard\"\u003e\n  \u0026nbsp;\u0026nbsp;\n  \u003cimg src=\"web/public/screenshot-android.png\" height=\"240\" alt=\"Android emulator\"\u003e\n\u003c/p\u003e\n\n## Quick start\n\n```bash\ngit clone git@github.com:ppietak/browserhut.git\ncd browserhut\nmake start\n```\n\nThis will:\n1. Download Bun, JDK 17, and Android SDK (~20 GB on first run)\n2. Start the backend server\n3. Open the dashboard in your browser\n\nFrom the dashboard, click **Start** on Android or Linux (or both).\n\n```bash\nmake stop      # shut down everything\nmake open      # re-open the dashboard\n```\n\n## What it does\n\n**Android emulator** — screen is streamed to a browser canvas via gRPC. Touch, keyboard, scroll, and pinch-zoom all work through the browser.\n\n**Linux desktop** — runs Chromium in a Docker container, displayed via noVNC. Keyboard input is captured and forwarded.\n\nBoth can run simultaneously.\n\n## Controls\n\n| Input | Action |\n|---|---|\n| Click / drag | Touch |\n| Scroll wheel | Vertical scroll |\n| `Shift` + scroll | Horizontal scroll |\n| Hold mouse button + scroll | Pinch zoom in/out |\n| `Cmd+C` / `Cmd+V` | Clipboard sync with Mac |\n| `Cmd+Arrow`, `Option+Arrow` | Mapped to Home/End, word nav |\n| Side buttons | Back, Home, Recents (Android) |\n\n## Requirements\n\n- **macOS** (tested on Apple Silicon)\n- **Docker**\n- ~20 GB disk on first run (JDK, SDK, system image, AVD)\n\n\u003e **Note:** No manual dependencies — Bun, JDK, and Android SDK are all downloaded automatically by `make start`.\n\n## Configuration\n\n```bash\nmake start API=33 IMAGE=google_apis_playstore\n```\n\n| Variable | Default | Description |\n|---|---|---|\n| `API` | `34` | Android API level |\n| `IMAGE` | `google_apis` | System image (`google_apis`, `google_apis_playstore`, `default`) |\n| `HEADLESS` | `0` | Set to `1` for no-window mode (CI) |\n| `WEB_PORT` | `3000` | Backend server port |\n| `GRPC_PORT` | `8554` | Emulator gRPC port |\n| `NOVNC_PORT` | `7900` | Linux noVNC port |\n\nEach API/image combination gets its own AVD (e.g. `emu-33-google_apis_playstore`).\n\n## Project structure\n\n```\nMakefile              # Downloads SDK, manages emulator and Linux container\nDockerfile.linux      # Chromium + xdotool + xclip on Selenium base image\nweb/\n  server.js           # Backend: gRPC bridge, WebSocket, REST API (runs on Bun)\n  public/\n    index.html        # Dashboard\n    android.html      # Android emulator view\n    linux.html        # Linux desktop view\n    styles.css        # Shared styles\n    dashboard.js      # Dashboard logic (REST polling)\n    android.js        # Emulator logic (WebSocket, canvas, input)\n    linux.js          # Linux logic (WebSocket, noVNC, keyboard)\n```\n\nEverything downloaded at runtime lives in gitignored directories:\n\n```\n.bun/                 # Bun runtime (auto-downloaded)\n.jdk/                 # Adoptium JDK 17\n.android-sdk/         # Android SDK, emulator, system images\n.avd/                 # AVD data\n```\n\n## Cleanup\n\n```bash\nmake clean            # delete AVDs (keep SDK/JDK)\nmake clean-all        # delete everything (.bun, .jdk, .android-sdk, .avd)\n```\n\n## License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fppietak%2Fbrowserhut","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fppietak%2Fbrowserhut","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fppietak%2Fbrowserhut/lists"}