The Problem

Managing wake-on-LAN (WoL) for a fleet of devices typically means SSHing into a machine or writing scripts. UpSnap puts that behind a web UI with user management, scheduled wake/shutdown via cron, and network scanning, so a small team can administer devices from a browser without touching a shell.

What This Does

UpSnap is a self-hosted WoL dashboard. The backend/ is a Go service built on PocketBase (a SQLite-backed API and admin UI), handling device wake, shutdown, sleep, and network scanning. The frontend/ is a SvelteKit app with i18n (23 translation files), theming, and pages for devices, users, settings, and account management.

The stack is deliberately small: Go for the networking layer, PocketBase for persistence and auth, SvelteKit for the UI, Docker for distribution. The backend/main.go starts PocketBase and registers custom handlers, while backend/networking/ contains the platform-specific implementations (Linux vs. other OSes) for pinging and sending magic packets.

How It Is Wired

Execution starts at main in backend/main.go, which calls StartPocketBase from backend/pb/pb.go. That function sets up the database, runs migrations, and registers HTTP handlers from backend/pb/handlers.goHandlerWake, HandlerShutdown, HandlerSleep, HandlerReboot, and HandlerWakeGroup.

The core path for a wake request is: HandlerWakeWakeDevice (in backend/networking/wake.go) → SendMagicPacket (in backend/networking/magicpacket.go) → getBroadcastIp + wakeUDP, which makes the outbound network call. WakeDevice also calls PingDevice (platform-specific, runs an external ping command) and KillProcess to manage background processes.

The most-connected functions — asyncCall (4 callers), PingDevice (3), KillProcess (2) — are the ones a change to would break the most. The cron system in backend/cronjobs/cronjobs.go (SetPingJobs, SetWakeShutdownJobs, etc.) schedules these operations, and StopAll stops them cleanly.

The module graph shows no circular dependencies, but the DeviceForm.svelte component at 721 lines is the largest single unit and routes a lot of UI logic through it.

How To Use It

git clone https://github.com/moses-y/UpSnap
cd UpSnap

# Run the backend directly
cd backend
go run main.go serve --http=0.0.0.0:8090

# Or run the frontend in dev mode
cd frontend
pnpm install
pnpm dev

For Docker, the docker-compose.yml uses network_mode: host and exposes the service on port 8090. Configuration is via environment variables (e.g., UPSNAP_HTTP_LISTEN for the port) and the PocketBase admin UI.

Real-World Use

A homelab operator with 10-20 machines (NAS, media servers, workstations) deploys UpSnap in Docker, adds each device's MAC and IP via the UI, and schedules a cron job to wake the backup server at 2 AM and shut it down at 6 AM. The network scan feature (requires nmap) discovers devices on the LAN to populate the dashboard. User management lets a team share the dashboard without handing out SSH access.

Code Health & Issues

Static analysis (deterministic, not opinion) found 19 findings: 9 high, 10 medium. The main issues:

  • High – Cognitive load: Deep nesting (max depth 9) in DeviceCard.svelte, DeviceCardNic.svelte, and DeviceForm.svelte. Fix with early returns/guard clauses.
  • High – Duplicated code: 88 repeated 6-line blocks across 11 files in backend/networking/. Extract shared helpers.
  • Medium – Oversized file: DeviceForm.svelte at 721 lines. Split by responsibility.

The code health audit flags a committed frontend/.env (tracked despite .gitignore), unpinned GitHub Actions (tags can be moved — a known supply-chain risk), and network_mode: host in Docker Compose (removes network isolation). It also recommends least-privilege GITHUB_TOKEN permissions, Dependabot, and pinning the alpine:3 base image by digest.

The Bottom Line

UpSnap is a functional, well-structured WoL dashboard that works out of the box for a homelab or small team. The Go backend is cleanly separated from the SvelteKit frontend. The main concerns are operational: a committed .env, unpinned CI actions, and host networking in Docker — all fixable in an afternoon. Worth deploying if you need WoL management without building it yourself.