The Problem

Enterprises and privacy‑focused users need to transcribe audio/video locally without sending any data to cloud services. Existing cloud APIs expose recordings and incur recurring fees, while self‑hosted solutions are often fragmented or lack a polished UI.

What This Does

Scriberr provides a full‑stack, offline transcription platform. The backend lives under internal/ and cmd/ and implements job orchestration, file handling, and API endpoints (see cmd/server/main.go, internal/api/handlers.go). The frontend is a React codebase in web/ that talks to the backend via the generated OpenAPI spec (api-docs/swagger.json). Core transcription adapters live in internal/transcription/adapters/ and wrap Python models (Parakeet, Canary, Whisper) through the base_adapter.go wrapper.

Key entry scripts:

  • cmd/scriberr-cli/main.go – CLI wrapper for one‑off transcription jobs.
  • cmd/server/main.go – Starts the HTTP server exposing /api/v1/* routes.

Docker support is provided by Dockerfile, Dockerfile.cuda*, and several docker‑compose*.yml files for CPU or GPU deployments.

How It Is Wired

Execution begins at cmd/server/main.go:func main(). It builds a logger (pkg/logger/logger.go), loads configuration, then calls SetupRoutes. SetupRoutes registers HTTP handlers from internal/api/handlers.go and injects AuthMiddleware.

Inside a request, UploadAudio (handler) stores the uploaded file via internal/service/file_service.go:SaveUpload, then creates a transcription job by calling internal/transcription/unified_service.go:ProcessJob. ProcessJob selects the appropriate adapter (internal/transcription/adapters/canary_adapter.go or others) and runs the external Python command (exec.Command) – one of the 10 functions that invoke external processes. The adapter writes intermediate files; file_service.go:RemoveFile cleans them up later.

The internal call graph shows the most widely used functions: Info (59 callers) and Create (44 callers) from pkg/logger/logger.go and repository layers, respectively. Changing these functions has the highest blast radius because they are called across many packages. No circular imports were detected, but several modules have high instability (e.g., web/frontend/src/components/ChatSessionsSidebar with 7 outgoing imports and none incoming), indicating they are leaf nodes that could be refactored without widespread impact.

The code touches external resources in three ways:

  • Filesystem/DB – internal/database/database.go opens a SQLite (or configured) DB and file_service.go manipulates uploaded media.
  • External commands – adapters invoke Python scripts for model inference.
  • Network – the server exposes a REST API; no outbound network calls are present in the core.

How To Use It

# Clone the repo (use the exact URL required)
git clone https://github.com/moses-y/Scriberr
cd Scriberr

# Build and run with Docker (CPU‑only example)
docker-compose -f docker-compose.yml up --build

# Or start the server locally
go build -o scriberr-server cmd/server/main.go
./scriberr-server   # listens on port 8080 by default

# Run a one‑off transcription via CLI
go build -o scriberr-cli cmd/scriberr-cli/main.go
./scriberr-cli transcribe --file path/to/audio.wav

Configuration files are not explicitly listed; the server expects environment variables for model paths and optional API keys (e.g., for Ollama/OpenAI integration). Those variables are read in internal/config (not shown) and must be set before starting the server.

Real‑World Use

A media‑archiving pipeline can drop new recordings into a watched folder (internal/cli/service.go:watchFiles). The folder watcher triggers ProcessJob, which runs the selected model on GPU (via Dockerfile.cuda) and stores the resulting transcript in the SQLite DB. A downstream service queries /api/v1/transcripts/:id to fetch timed text for further analysis or UI rendering.

Code Health & Issues

  • Critical – golang.org/x/crypto@0.41.0 has CVE‑2026‑42508; upgrade and update go.mod lockfile.
  • High – Pin GitHub Action goreleaser/goreleaser-action@v6 to a commit SHA.
  • High – golang.org/x/net@0.43.0 carries CVE‑2026‑25680; upgrade.
  • Medium – Declare least‑privilege permissions for GITHUB_TOKEN in .github/workflows/ci.yaml.
  • Medium – Enable Dependabot or Renovate (.github/dependabot.yml).
  • Medium – Pin Docker base images by digest in Dockerfile.
  • Medium – Add a dependency‑vulnerability scan step to CI.
  • Medium – Move large binaries (>5 MiB) to Git LFS.
  • Medium – Set persist-credentials: false on checkout steps.
  • Medium – Add a non‑root USER to Docker images.

Additional static findings include deep nesting (max depth 8) in several React components, duplicated 6‑line blocks across 73 files, and oversized source files (>5 k lines) that would benefit from modularization.

The Bottom Line

Scriberr delivers a complete offline transcription stack with a modern UI and GPU support, but the codebase suffers from several high‑severity dependency vulnerabilities and maintainability hotspots (deep nesting, duplicated logic). It is suitable for teams comfortable with Go, Docker, and React who can address the security fixes and refactor the most complex components before production use.