The Problem

Neko solves the problem of sharing a real, interactive desktop browser session with multiple remote users over the internet. Traditional screen-sharing tools are latency-heavy and require one user to drive. Neko replaces that with a self-hosted, containerized browser that streams over WebRTC, so each participant gets low-latency video and can control the same session simultaneously—useful for watch parties, collaborative browsing, or demoing web apps without exposing a local machine.

What This Does

This is a fork of the popular m1k1o/neko project. It runs a browser (Chromium, Firefox, Brave, etc.) inside a Docker container, captures the display via Xorg, and streams it to clients using WebRTC. The server, written in Go (server/), handles WebSocket signaling, member management, and capture. The client (client/) is a TypeScript/React app that renders the video stream and sends input events back to the server.

The repo is structured as five independent projects: server/ (Go backend), client/ (React frontend), webpage/ (marketing site), apps/ (per-browser Dockerfiles), and utils/ (helper tools). Each has its own build and dependencies. The apps/ directory contains Dockerfiles for Chromium, Firefox, Brave, KDE, and Edge, including NVIDIA variants for GPU-accelerated encoding.

How It Is Wired

Execution starts in the Go server (server/cmd/), which initializes the WebSocket handler (server/internal/websocket/handler/). The control.go file routes incoming messages—members join, send input events, and receive stream metadata. The server captures the X11 display via server/internal/capture/ and encodes it to WebRTC. The client connects via client/src/neko/index.ts, which establishes the WebSocket and WebRTC peer connection, then renders video in client/src/components/video.vue.

The import graph shows client/src/store/index.ts as a hub (Ca 2, Ce 8), importing locale, neko base, and utility modules—changes there ripple broadly. The client/src/neko/events.ts module is a pure leaf (Ca 3, Ce 0), so it's safe to modify. No circular dependencies were detected. The server's server/internal/config/capture.go has deep nesting (indentation depth 11), making it the hardest file to reason about.

How To Use It

Setup requires Docker. Build a base image, then an app image:

git clone https://github.com/moses-y/neko
cd neko
docker build -f apps/chromium/Dockerfile -t neko-chromium .
docker run -p 8080:8080 -e NEKO_PASSWORD=secret neko-chromium

Configuration lives in environment variables (e.g., NEKO_PASSWORD, NEKO_BIND) and is read by server/internal/config/. The client is served from the same container. No Makefile exists; Docker is the only supported path.

Real-World Use

A team runs Neko on a small VPS to demo a web app to remote stakeholders. They launch the Chromium container, share the URL and password, and each participant controls the same browser session. The server's server/internal/member/ tracks who's connected and enforces roles (viewer vs. controller). For GPU-accelerated encoding, they'd use apps/chromium/Dockerfile.nvidia with the NVIDIA container runtime.

Code Health & Issues

Static analysis found 33 findings (5 high, 18 medium, 10 low). High severity: deep nesting in server/internal/plugins/dependency_test.go and server/internal/config/capture.go (indentation depth 11); duplicated 6-line blocks across 46 files (e.g., apps/chromium/widevinecdm.sh); oversized files like server/pkg/xorg/keysymdef.go (2184 lines). Medium: empty catch block in client/src/neko/base.ts, high branching density in server/internal/websocket/handler/control.go (60 branch points over 177 lines). Low: unresolved TODO markers in server/internal/http/legacy/wstoclient.go (7) and utils/xorg-deps/xf86-video-dummy/v0.3.8/ltmain.sh (9).

SDLC observations: CI exists (GitHub Actions) but no workflow runs the test suite. GitHub Actions are pinned to mutable tags (@v3), not commit SHAs—a supply-chain risk. No Dependabot, no dependency vulnerability scan, and persist-credentials is not disabled on checkout. Base images use mutable tags. Test coverage is thin: 3 test files against 232 source files.

The Bottom Line

This is a functional fork of a well-known project, with a clean separation between server, client, and app images. The Go backend is solid, but the client has moderate complexity and the CI pipeline needs hardening (pinned actions, actual test execution, dependency scanning). Use it if you need a self-hosted, multi-user browser streaming solution and can invest in the operational hygiene.