The Problem
Developers need an on‑premise way to surface runtime events (builds, errors, alerts) on their phones without relying on third‑party SaaS, credentials leakage, or extra telemetry pipelines. Existing solutions either require cloud accounts or involve complex self‑hosting stacks.
What This Does
Boop delivers a single‑binary Go server that stores events in a local SQLite file and pushes them directly to Apple APNs. An iOS SwiftUI client polls the server for full event data, while a Svelte web UI (compiled into the binary) lets you create projects, pair devices, and view the inbox. The whole stack lives in three top‑level folders:
server/– Go API, SQLite persistence, APNs handling, embedded Svelte UI.ios/– SwiftUI app, networking (APIClient.swift), push handling (PushManager.swift).server/web/– Svelte source (src/), TypeScript helpers (src/lib/*.ts), built by Vite.
Key files: server/cmd/boop/main.go (binary entry), server/internal/api/api.go (HTTP router), server/internal/apns/apns.go (APNs client), ios/Boop/App/BoopApp.swift (app startup), server/web/src/main.ts (Svelte entry).
How It Is Wired
Start → Go binary – server/cmd/boop/main.go parses env vars (.env.example), creates a SQLite DB (data/boop.db), and calls internal/api.NewRouter() (in api.go). The router registers /api/v1/events → internal/events.HandleCreate (in events.go).
Event POST – HandleCreate validates the bearer token (auth.go), redacts sensitive fields (redact.go), stores the row via internal/database.InsertEvent (in database.go), then spawns an APNs push through internal/apns.Push(event) (calls apns.go).
APNs push – apns.go builds a minimal payload (title, body, event ID) and uses the .p8 key configured via env (APNS_KEY_ID, APNS_TEAM_ID, etc.) to send to Apple. Failure logs but does not block DB write.
iOS client fetch – On receipt of the push, ios/Boop/Notifications/PushManager.swift extracts the event ID, then APIClient.fetchEvent(id:) (in APIClient.swift) GETs /api/v1/events/{id} → internal/events.HandleGet which reads the full JSON from SQLite and returns it.
Web UI – The Svelte app is served by internal/web/web.go, which embeds the compiled assets (server/web/dist/*). UI actions (e.g., creating a project) call the same Go API endpoints, sharing the same code paths as the iOS client.
Data flow summary – main.go → router → auth → redact → DB write → APNs push → iOS/Swift fetch → DB read → UI render. The only module with a wide blast radius is internal/api because it routes every external request; changes here affect both mobile and web clients. No circular dependencies are evident; the graph is a clear tree from entry points down to DB or network layers.
How To Use It
# Clone the repo
git clone https://github.com/moses-y/boop && cd boop
# Copy env template (contains BOOP_BASE_URL, APNS_* vars, BOOP_API_KEY)
cp .env.example .env
# Build and start via Docker (recommended)
docker compose up -d --build # uses docker-compose.yml & server/Dockerfile
# Or run the Go binary directly
make build # produces ./bin/boop
./bin/boop # reads ./data/boop.db, serves on :8080
Configuration – Edit .env for the APNs credentials (APNS_KEY_ID, APNS_TEAM_ID, APNS_PRIVATE_KEY, APNS_TOPIC). The server will create data/boop.db on first start.
Running the iOS app – Open ios/Boop.xcodeproj in Xcode, set the bundle identifier, add your APNs key, and build for a device or simulator. The app reads the server URL from its bundled config (see ios/Boop/Info.plist).
Web UI – After the server is up, visit http://localhost:8080 to run the setup wizard, create a project, and obtain the API key for POSTs.
Real‑World Use
A CI pipeline can notify developers of failed builds:
curl http://localhost:8080/api/v1/events \
-H "Authorization: Bearer $BOOP_PROJECT_KEY" \
-H "Content-Type: application/json" \
-d '{"title":"CI failure","level":"error","data":{"job":"test","branch":"main"}}'
The push appears instantly on paired iPhones; the web UI retains a searchable history for audit.
Code Health & Issues
- Low – No license file in the fork (original repo has MIT, but the fork lacks it).
- Low – Secrets not present, but
.env.examplecontains placeholder APNs variables; ensure they are never committed with real values. - Low – CI defined in
.github/workflows/ci.ymlrunsgo test ./...andnpm testfor the web UI; test coverage appears adequate (17 test files). - No structural red flags detected; the repository includes lock files, CI, and a Makefile.
The Bottom Line
Boop offers a compact, self‑hosted notification pipeline with a clear Go‑centric backend, a lightweight Svelte UI, and a native iOS client. It is well‑structured for small teams that need on‑prem alerts without external dependencies, but the fork’s missing license and lack of documented production hardening mean you should audit security before a public rollout.