LizardByte/Sunshine
Self-hosted game stream host for Moonlight.
Healthy across the board
weakest axiscopyleft license (GPL-3.0) — review compatibility
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit today
- ✓18 active contributors
- ✓Distributed ownership (top contributor 32% of recent commits)
Show all 7 evidence items →Show less
- ✓GPL-3.0 licensed
- ✓CI configured
- ✓Tests present
- ⚠GPL-3.0 is copyleft — check downstream compatibility
What would change the summary?
- →Use as dependency Concerns → Mixed if: relicense under MIT/Apache-2.0 (rare for established libs)
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/lizardbyte/sunshine)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/lizardbyte/sunshine on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: LizardByte/Sunshine
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/LizardByte/Sunshine shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across the board
- Last commit today
- 18 active contributors
- Distributed ownership (top contributor 32% of recent commits)
- GPL-3.0 licensed
- CI configured
- Tests present
- ⚠ GPL-3.0 is copyleft — check downstream compatibility
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live LizardByte/Sunshine
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/LizardByte/Sunshine.
What it runs against: a local clone of LizardByte/Sunshine — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in LizardByte/Sunshine | Confirms the artifact applies here, not a fork |
| 2 | License is still GPL-3.0 | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 30 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of LizardByte/Sunshine. If you don't
# have one yet, run these first:
#
# git clone https://github.com/LizardByte/Sunshine.git
# cd Sunshine
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of LizardByte/Sunshine and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "LizardByte/Sunshine(\\.git)?\\b" \\
&& ok "origin remote is LizardByte/Sunshine" \\
|| miss "origin remote is not LizardByte/Sunshine (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(GPL-3\\.0)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"GPL-3\\.0\"" package.json 2>/dev/null) \\
&& ok "license is GPL-3.0" \\
|| miss "license drift — was GPL-3.0 at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "CMakeLists.txt" \\
&& ok "CMakeLists.txt" \\
|| miss "missing critical file: CMakeLists.txt"
test -f ".github/workflows/ci.yml" \\
&& ok ".github/workflows/ci.yml" \\
|| miss "missing critical file: .github/workflows/ci.yml"
test -f "cmake/prep/options.cmake" \\
&& ok "cmake/prep/options.cmake" \\
|| miss "missing critical file: cmake/prep/options.cmake"
test -f "cmake/dependencies/common.cmake" \\
&& ok "cmake/dependencies/common.cmake" \\
|| miss "missing critical file: cmake/dependencies/common.cmake"
test -f ".prettierrc.json" \\
&& ok ".prettierrc.json" \\
|| miss "missing critical file: .prettierrc.json"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 30 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~0d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/LizardByte/Sunshine"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
Sunshine is a self-hosted game streaming server that broadcasts games to Moonlight clients over a network, similar to NVIDIA GeForce Now or Steam Remote Play. It captures GPU-accelerated video/audio output on Windows, macOS, and Linux, encodes it efficiently (HEVC, H.264), and streams to remote Moonlight decoders with sub-100ms latency. The core capability is enabling low-latency game streaming from a personal PC to any device that runs Moonlight. Monolithic architecture: src/ contains the C++ streaming engine (GPU capture, encoding, networking), cmake/ holds platform-specific build configuration, apps/web/ is the Vue 3 admin UI (vite-bundled), and tests/ has integration fixtures. The build is orchestrated by CMakeLists.txt which conditionally compiles platform-specific code (compile_definitions/linux.cmake, compile_definitions/common.cmake). Dockerfiles show it's designed as a single containerized service, not microservices.
👥Who it's for
Game enthusiasts and home server builders who want to stream their existing game library to other devices (phones, tablets, other PCs) without relying on cloud services; also reverse-engineering enthusiasts interested in the Moonlight protocol (GPU encoding, codec selection, input handling). Contributors are C++ systems programmers and full-stack developers (the project has 2M+ lines of C++, CMake build orchestration, and a Vue 3 web UI).
🌱Maturity & risk
Actively developed and production-ready. The project has robust CI across 10+ platforms (.github/workflows/ci-*.yml files), a mature release process with Docker/Flathub/Winget/Homebrew integration, 2M+ lines of well-structured C++, and appears to have regular updates (visible from the 10 different platform-specific CI workflows). It's used by thousands (implied by Docker/Flathub pull metrics), with established packaging in multiple distributions.
Low-to-moderate risk for active users, higher risk for maintainability. The codebase is deeply coupled to GPU vendor APIs (NVIDIA CUDA, AMD encoding, Intel Quick Sync, Wayland/X11, macOS Metal) and platform-specific video capture (Windows DXGI, Linux DRM/libva), making cross-platform bugs subtle. CMake dependency resolution is complex (custom FindLibva.cmake, FindWayland.cmake, etc.), and the single-language focus (C++ backend + Vue frontend) means backend changes require C++ knowledge. The enormous C++ codebase (2M LOC) has inherent maintenance burden despite active CI.
Active areas of work
Unable to determine from file metadata alone (no recent commit dates in provided data), but the presence of 10+ active CI workflows (ci-linux.yml, ci-windows.yml, ci-macos.yml, ci-archlinux.yml, ci-freebsd.yml, ci-homebrew.yml, ci-flatpak.yml, ci-copr.yml, ci-bundle.yml), active dependabot.yml configuration, and elaborate GitHub Actions (localize.yml, release-notifier-moonlight.yml, update-pages.yml) indicate continuous integration and multi-platform release cycles. The codebase has Copilot instructions (.github/copilot-instructions.md), suggesting active development tooling.
🚀Get running
Clone the repo and initialize submodules, then build with CMake:
git clone https://github.com/LizardByte/Sunshine.git
cd Sunshine
git submodule update --init --recursive
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build . -j$(nproc)
For the Vue frontend (apps/web/), you can also develop in isolation:
cd apps/web
npm install
npm run dev # or 'npm run build' for production
Daily commands: For the web UI dev server only:
cd apps/web
npm install
npm run dev # Vite watch-mode dev server
npm run build # Production bundle
npm run serve # Serve test fixtures from tests/fixtures/http
For the full streaming server (requires platform-specific GPU drivers and dependencies, see cmake/FindLibva.cmake, FindWayland.cmake, etc.):
cd build
cmake --build . --target sunshine # or cpack for distributable packages
🗺️Map of the codebase
CMakeLists.txt— Root build configuration for the entire C++ project; defines all targets, dependencies, and platform-specific compilation rules..github/workflows/ci.yml— Master CI/CD pipeline orchestrating builds across Windows, macOS, Linux, and FreeBSD; entry point for understanding release and test automation.cmake/prep/options.cmake— Defines all build-time feature flags and configuration options that control which features are compiled into Sunshine.cmake/dependencies/common.cmake— Central dependency manifest for cross-platform libraries (FFmpeg, Boost, nlohmann_json, Opus, etc.); critical for understanding external integrations..prettierrc.json— Code formatting standard for the entire project; enforces consistency across web UI (Vue/TypeScript) and documentation.package.json— Frontend build configuration using Vite + Vue 3; defines web UI tooling, dependencies, and development workflow.crowdin.yml— Internationalization workflow configuration; critical for understanding how translations are managed across the project.
🛠️How to make changes
Add a new platform-specific build feature
- Add feature toggle in cmake/prep/options.cmake with OPTION(OPTION_MY_FEATURE "description" ON/OFF) (
cmake/prep/options.cmake) - Define platform-specific logic in cmake/compile_definitions/[platform].cmake using if(OPTION_MY_FEATURE) (
cmake/compile_definitions/linux.cmake) - Link required dependencies in cmake/dependencies/[platform].cmake if libraries are needed (
cmake/dependencies/linux.cmake) - Add a new CI workflow in .github/workflows/ or modify ci-[platform].yml to test the feature (
.github/workflows/ci-linux.yml)
Add a new web UI page or component
- Create Vue component in src/pages/ or src/components/ following existing Vue 3 Composition API patterns (
package.json) - Register component and route in the main app initialization file (typically src/main.ts or src/App.vue) (
package.json) - Add i18n translation keys in src/locales/[lang].json for all user-visible strings (
crowdin.yml) - Ensure component uses Bootstrap 5 utility classes for styling consistency (
package.json)
Add support for a new Linux distribution
- Create a new .dockerfile in docker/ directory (e.g., docker/fedora.dockerfile) based on existing distributions (
docker/ubuntu-24.04.dockerfile) - Add a new CI workflow ci-[distro].yml in .github/workflows/ that builds and tests on the new distribution (
.github/workflows/ci-archlinux.yml) - Update cmake/dependencies/linux.cmake if the distro uses different package names or libraries (
cmake/dependencies/linux.cmake) - Add packaging configuration in cmake/packaging/linux.cmake for the distro's native package manager (
cmake/packaging/linux.cmake)
Add a new API endpoint
- Document the endpoint in docs/api.md with path, method, request/response schemas, and examples (
docs/api.md) - Implement the endpoint handler in the C++ backend (typically in src/web/ or src/rest/) (
CMakeLists.txt) - Add TypeScript client method in frontend src/api/ to call the new endpoint with proper type checking (
package.json) - Create integration tests in the CI workflow or test suite to verify endpoint functionality (
.github/workflows/ci.yml)
🔧Why these technologies
- C++ with CMake — Provides low-latency hardware-level access for GPU encoding, real-time input handling, and minimal resource overhead required for game streaming on server hardware.
- Vue 3 + Vite frontend — Modern reactive UI for server configuration; Vite provides fast development iteration and production bundling; Bootstrap 5 ensures responsive design across devices.
- FFmpeg + libva/libdrm + NVENC/AMFENC — Unified codec abstraction supporting H.264/H.265 encoding across Intel (libva), AMD (libdrm), NVIDIA (NVENC), and fallback software encoding.
- Docker multi-distribution — Eliminates host environment variability; enables consistent builds and deployment across Ubuntu, Debian, Fedora, and other distributions.
- GitHub Actions matrix CI — Parallel testing across Windows, macOS, Linux (multiple distros), and FreeBSD ensures cross-platform compatibility at each commit.
- Crowdin internationalization — Centralized translation management for UI and documentation; enables community localization without modifying source code.
⚖️Trade-offs already made
-
Hardware encoding as primary path with software fallback
- Why: Hardware encoding (NVENC/AMFENC) provides dramatically lower latency and CPU usage, but not all hardware supports it.
- Consequence: Added complexity in codec negotiation and capability detection, but enables low-latency streaming on commodity hardware.
-
Self-hosted REST API with TLS instead of proxy authentication
- Why: Simpler deployment for local networks; users control the certificate and private key.
- Consequence: No built-in multi-user access control or cloud integration; users must manage TLS certificates themselves.
-
Separate C
- Why: undefined
- Consequence: undefined
🪤Traps & gotchas
GPU drivers required: the binary will fail silently if NVIDIA drivers (for CUDA), AMD drivers (for VCE), or Intel drivers (for QSV) are missing on their respective platforms. Wayland vs X11 on Linux requires different code paths (see cmake/FindWayland.cmake). CMake dependency chain is long and platform-specific—missing libva, libdrm, or libcap on Linux breaks compilation. Audio capture on Windows requires WASAPI, on Linux requires PipeWire or ALSA (not auto-detected). Moonlight protocol reverse-engineering is core; protocol version mismatches between server and client cause streaming failures. Web UI CORS and self-signed certificates required for HTTPS admin console (see apps/web setup). Docker build requires multi-stage setup to avoid bloated images (see .dockerignore).
🏗️Architecture
💡Concepts to learn
- GPU-accelerated video encoding (NVENC, VCE, Quick Sync) — Sunshine's core performance advantage: encoding video in hardware (not CPU) is essential for 60+ FPS streaming without frame drops; understanding codec selection (H.264 vs HEVC) and encoder fallbacks is critical to debugging stream quality issues
- VA-API (Video Acceleration API) — Sunshine's abstraction layer for GPU encoding on Linux; replacing GPU-specific code paths (NVIDIA CUDA, AMD) with vendor-agnostic VA-API calls. New Linux GPU support requires understanding VA-API's query/profile system.
- Real-time streaming protocols (RTMP, Moonlight's custom protocol) — Sunshine implements a custom low-latency streaming protocol (reverse-engineered from Moonlight clients). Understanding latency budgets, frame acknowledgments, and packet loss recovery is essential for optimizing stream quality.
- Screen capture APIs (DXGI, DRM, Metal, Wayland protocols) — Sunshine must capture raw frames from the GPU before encoding; each platform (Windows DXGI, Linux DRM, macOS Metal) has different APIs and latency characteristics. Platform-specific bugs here cause entire streaming pipeline failures.
- Input event forwarding and synchronization — Moonlight sends keyboard/mouse/gamepad events over the network; Sunshine must inject them into the OS (Windows sendinput, Linux uinput, macOS Quartz events) with precise timing to minimize perceived latency.
- Adaptive bitrate control — Sunshine monitors network conditions and adjusts encoding bitrate/resolution dynamically to prevent buffering; this requires feedback loops between encoder and network stack.
- CMake conditional compilation and platform detection — Sunshine's build system conditionally includes platform-specific code (Linux vs Windows vs macOS, Wayland vs X11) using compile_definitions/ and FindXXX.cmake modules; understanding this is mandatory for cross-platform contributions.
🔗Related repos
moonlight-stream/moonlight-qt— Official Moonlight client for desktop; the reference implementation of the protocol that Sunshine's server streams tomariotaku/moonlight-android— Moonlight client for Android phones/tablets; completes the ecosystem of devices Sunshine can stream tochromaprint/chromaprint— Audio fingerprinting library sometimes used in similar media streaming contexts; less directly related but represents audio handling complexity in streaming stacksFFmpeg/FFmpeg— Industry-standard video/audio encoding framework that Sunshine uses internally for codec operations and transcoding fallbacksros-infrastructure/catkin— CMake-based build orchestration (unrelated project, but demonstrates complex multi-platform CMake patterns similar to Sunshine's compile_definitions/
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add Vue component unit tests for the web UI
The repo has a Vue 3 frontend (package.json shows vue, vue-i18n, bootstrap dependencies) but no test files are visible in the file structure. With Vite as the build tool, adding Vitest + @vue/test-utils would enable testing of UI components. This is critical for a project with i18n, icons, and markdown rendering that affects user experience.
- [ ] Add vitest and @vue/test-utils to devDependencies in package.json
- [ ] Create tests/ directory for Vue component tests
- [ ] Add test script to package.json ("test": "vitest")
- [ ] Create example unit tests for any main Vue components in src/
- [ ] Add vitest config to vite.config.js and update .gitignore for coverage/
Add CMake dependency update workflow for C++ libraries
The repo uses CMake with many external dependencies (FFmpeg, Boost, Opus, Wayland, libva, etc. in cmake/dependencies/). While there's a dependabot.yml for GitHub actions, there's no automated checking for outdated C++ library versions. Adding a workflow to periodically check and report outdated cmake dependencies would help maintainers stay current with security patches.
- [ ] Create .github/workflows/check-cmake-deps.yml workflow
- [ ] Use tools like cmake-format-checker or custom script to parse cmake/dependencies/ files
- [ ] Add job to check latest versions of common deps (FFmpeg, Boost, etc.) against their releases
- [ ] Create automated issue or PR comment with outdated package report
- [ ] Schedule workflow to run weekly or monthly
Document the cmake/macros and cmake/dependencies organization with inline comments
The cmake/ directory has fragmented configuration across platform-specific files (linux.cmake, macos.cmake, windows.cmake, unix.cmake) with no clear documentation on the purpose of macros/ vs dependencies/ directories or the override/include patterns. New contributors working on platform support or dependency management will struggle. Adding structured comments and a cmake/README.md would significantly improve maintainability.
- [ ] Create cmake/README.md explaining directory structure and include patterns
- [ ] Add header comments to cmake/macros/common.cmake, linux.cmake, etc. describing purpose
- [ ] Add comments in cmake/dependencies/common.cmake explaining dependency resolution order
- [ ] Document platform-specific override logic (when unix.cmake vs linux.cmake is used)
- [ ] Include examples of how to add new dependencies or platform-specific flags
🌿Good first issues
- Add unit tests for apps/web/src/ Vue components (currently only integration fixtures in tests/fixtures/http/). Start with a simple component test using Vitest + Vue Test Utils to build confidence in the testing setup.
- Document the Moonlight protocol handshake in a new docs/PROTOCOL.md file by reverse-engineering the existing C++ client code in src/ and cross-referencing the official Moonlight documentation. This unblocks new contributor understanding of the core streaming mechanism.
- Add GitHub Actions matrix job to ci-linux.yml to test compilation with deprecated GPU libraries (old libva, old libdrm) to catch breaking changes early. This would prevent silent build failures on older distros.
⭐Top contributors
Click to expand
Top contributors
- @dependabot[bot] — 32 commits
- @renovate[bot] — 16 commits
- @neatnoise — 12 commits
- @Kishi85 — 10 commits
- @ReenigneArcher — 9 commits
📝Recent commits
Click to expand
Recent commits
810783d— build(windows): Always setup Node.js in Windows CI (#5084) (ReenigneArcher)3d84916— fix: show actual bind address in Web UI log message (#4897) (aliefe04)c6988fd— build(web-ui): commit lock file (#5083) (ReenigneArcher)888a6bb— Merge commit from fork (ReenigneArcher)bfae5de— chore(deps): update dependency vue-i18n to v11.4.2 (#5080) (renovate[bot])ecdb034— build(linux): fix gcov detection for ArchLinux (#5081) (ReenigneArcher)0899b34— build(linux): add ubuntu 26.04 support (#5051) (ReenigneArcher)8362d58— chore(deps): update dependency vue to v3.5.34 (#5078) (renovate[bot])68dfcce— build(deps): bump packaging/linux/flatpak/deps/flatpak-builder-tools from1895ec8todda10aa(#5077) (dependabot[bot])a241c78— feat(linux/wlgrab): match output_name by xdg_output name (#5071) (netanelbi)
🔒Security observations
Failed to generate security analysis.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.