Systems Engineering • Application Architecture
Antialgo: An Offline-First, Privacy-First Media Library
Quick Links
Antialgo is a systems-design statement as much as an app: the privacy and ownership goals dictated a local-first architecture, not the other way around. Making the browser the source of truth — and the server strictly optional — is what lets the product credibly claim it isn’t watching you. The ingestion layer that normalizes its five media sources is documented separately.
Summary
- Problem: Media apps default to the cloud and to algorithms — they own your library and shape what you consume.
- Solution: Invert it. Keep state in the browser by default, make server sync opt-in, and remove recommendations entirely.
- Impact: A media library the user fully owns — works without a backend, syncs across devices when they want it to, and never profiles them.
Context
Antialgo is a reaction to algorithmic media platforms. The design constraint — privacy and ownership — drove the architecture; the app has to be useful with no server at all, and any server involvement has to be the user's explicit choice. That ruled out the usual "everything in the cloud, personalize via tracking" shape.
Goals, Requirements, Constraints
Goals
- Work fully client-side with no backend required
- Make multi-device sync opt-in via self-hosted PostgreSQL
- No tracking, no recommendation algorithms, no engagement mechanics
- Handle five media types (video, music, audiobooks, books, podcasts) under one interface
Constraints
- Default storage is the browser (localStorage); the server is optional
- Self-hostable with a small ops footprint
- Strict TypeScript throughout
Approach
State is local-first — the browser is the source of truth via localStorage, so the app is fully functional offline and without a backend. When a user opts into multi-device sync, a self-hosted PostgreSQL instance backs their data. Media metadata is parsed in the app from the files themselves (ID3 tags, audiobook chapters, EPUB structure), uploads stream through a multipart parser, and auth is a custom JWT implementation rather than a third-party provider.
Key Design Decisions
- Decision: Local-first state with opt-in server sync
Why: Privacy and ownership are the product. localStorage as the default source of truth means the app needs no backend to work and collects nothing; PostgreSQL sync is there only when the user wants cross-device continuity.
Alternatives: Server-authoritative state is simpler to reason about but contradicts the entire premise. - Decision: No recommendation engine, by design
Why: The whole point ("antialgo") is to remove algorithmic curation. The user organizes and filters their own library; the system never decides what they should consume next.
Alternatives: Even a benign "you might like" feature would reintroduce the engagement dynamics this avoids. - Decision: Parse media metadata in-app from the files
Why: ID3 tags, audiobook chapters (M4B), and EPUB structure are extracted client-side so a rich library can be built without uploading anything to a third party.
Alternatives: A metadata API would add a dependency and leak the user's library contents. - Decision: Custom JWT auth (jose/HS256 + bcrypt)
Why: Self-hosted and dependency-light; no external auth provider to trust or pay for.
Alternatives: Auth0/Firebase would be faster to wire but reintroduce a third party into a privacy-first app.
Implementation
Components / Modules
- Local-first store: Browser localStorage as the default source of truth; the app runs fully without a backend.
- Optional PostgreSQL sync: Opt-in server persistence for multi-device continuity; self-hosted.
- In-app metadata extraction: music-metadata for ID3 tags, jszip/fast-xml-parser for audiobook chapters and EPUB structure; reading/listening position tracked per item.
- Streaming uploads + custom auth: busboy for multipart upload parsing; custom JWT (jose/HS256) with bcrypt password hashing.
Data & State
- Source of truth: browser localStorage by default; PostgreSQL only when sync is enabled
- Media metadata derived client-side from the files; nothing uploaded to third parties
Security
- Profiling/tracking: there is none — no analytics, no recommendation engine, no third-party calls by default
- Data lock-in: data lives in the user's browser and (optionally) their own database
Controls Implemented
- Custom JWT auth (jose/HS256) with bcrypt password hashing — no third-party auth provider
- Self-hosted deployment (nginx + PM2 + PostgreSQL bound to localhost) behind TLS
- Server involvement is opt-in; the default path collects nothing
Verification
- Vitest covers core logic
- PostgreSQL bound to 127.0.0.1 in the documented deployment; reachable only via the app
Operations
Observability
- Minimal by design — no analytics or tracking is itself the privacy guarantee
Incident Response
- Lost device: if sync was enabled, data restores from the user's PostgreSQL; if not, it was always local by choice
Cost Controls
- Runs from a single self-hosted node (PM2 + nginx + PostgreSQL); no managed services, no CDN
Results
Outcomes
- Ownership: The library lives in the user's browser and, optionally, their own database — never a vendor's cloud.
- Privacy: No tracking and no recommendation engine; the default path makes no third-party calls.
- Resilience: The app is fully functional offline and without a backend, because local is the default, not a fallback.
Tradeoffs
- Local-first means conflict-resolution and sync semantics are the app's problem, not a backend's
- No recommendations means discovery is fully user-driven — intentional, but a different UX bet
Next Steps
- Stronger conflict resolution for concurrent multi-device edits
- Optional end-to-end encryption for the sync layer