Skip to content

Repository files navigation

The Social Wire

A reader for the standard.site publishing ecosystem, built on ATProto.

Overview

The Social Wire lets you read publications from people you follow on Bluesky and the broader ATProto network. Your reading preferences — folders, publication organisation — are stored on your own ATProto PDS, not on our servers.

Web (Next.js 16.2+)     iOS/iPadOS (SwiftUI)
       │                        │
       └─── ATProto OAuth ──────┘
                   │
       ┌───────────┴───────────┐
       ▼                       ▼
User's ATProto PDS      Social Wire gateway (Railway)
  app.thesocialwire.*     /xrpc/app.thesocialwire.* + compatibility /v1/*
  link.latr.saved.*       bootstrap stream, PDS write-through, /v1/latr/*
                               │
                               └── AppView + replicated indexing services
                                   Redis (disposable cache/leases)
                                   Postgres (durable derived state)

The current checkout adds Lexicon-defined /xrpc/app.thesocialwire.* aliases and migrates eligible clients to them. As verified on 2026-08-12, those aliases are not yet registered on the public Testing or Production gateways; deployed clients still use the retained /v1/* contract until the migration ships.

Monorepo Structure

the-social-wire/
  apps/
    web/             # Next.js 16.2+ reader (Bun)
    apple/           # SwiftUI iOS/iPadOS app
    operations/      # Next.js operator console (Bun)
  services/
    gateway/         # OAuth, sync, PDS writes, AppView proxy (Hummingbird; Railway)
    appview/         # Publication sidebar + Thin AppView read index (Railway)
    appview-worker/  # Compatibility executable + reusable AppView worker core
    jetstream-ingest/ # Replicated multi-lane Ingress Controller (Go; Railway)
    indexing-worker/ # Projection Pool / Coordinator shared runtime (Swift; Railway)
    operations/      # Operations control plane (Railway)
  packages/
    lexicons/        # record schemas plus app.thesocialwire.* service XRPC lexicons
    spec/            # OpenAPI 3.1 compatibility contract + endpoint manifest
    swift/           # GatewayCore, OperationsCore, SocialWireRedis, ThinAppViewCore
  database/
    migrations/      # Provider-neutral Postgres migration history
  docs/
    architecture/
    wiki/        # Canonical public wiki Markdown (GitHub sync; manual Lichen publish)

Prerequisites

Tool Version
Bun Matches root package.json packageManager (currently 1.3.x)
Swift 6.2+ for service/package test parity (CI uses 6.2.4)
Go 1.26.5 for the Jetstream V2 ingress service
Railway CLI Latest (hosted operations and migration access)
Xcode 16+ (for iOS)

Quick Start

Local development

# 1. Install JS dependencies
bun install

# 2. Start the web app
cd apps/web
cp .env.example .env.local
# Optional: uncomment or set vars in .env.local (defaults work for local OAuth loopback)
bun run dev

Open http://localhost:3000.

Full-stack local dev (optional)

The service executables currently accept only APP_ENV=dev|prod because their shared Operations namespace rejects local. Use an isolated disposable Postgres database for local integration; never point these commands at a hosted Development or Production database.

# Apply migrations to an isolated disposable Postgres database first.
DATABASE_URL='postgresql://…' bash scripts/apply-database-migrations.sh

# Run each service in a separate terminal with the same disposable DATABASE_URL.
# Gateway (OAuth, sync, writes)
(cd services/gateway && APP_ENV=dev DATABASE_URL='postgresql://…' APPVIEW_BASE_URL=http://127.0.0.1:8081 GATEWAY_APPVIEW_INTERNAL_SECRET=local-development-only PDS_ATTESTATION_RECEIPT_SECRET=local-development-attestation-receipt-secret swift run Gateway)

# AppView (sidebar + Thin AppView reads)
(cd services/appview && APP_ENV=dev DATABASE_URL='postgresql://…' ENABLE_THIN_APPVIEW=true GATEWAY_APPVIEW_INTERNAL_SECRET=local-development-only swift run AppView)

# Replicated projection role (AppView + Wire durable inboxes)
(cd services/indexing-worker && APP_ENV=dev DATABASE_URL='postgresql://…' ENABLE_THIN_APPVIEW=true INDEXING_WORKER_ROLE=projection swift run IndexingWorker)

Running tests

See docs/test-plans/README.md for per-surface plans and PR checklists.

(cd apps/web && bun test)
(cd apps/operations && bun test)
(cd packages/swift/GatewayCore && swift test)
(cd packages/swift/SocialWireRedis && swift test)
(cd services/gateway && swift test)
(cd services/appview && swift test)
(cd packages/swift/ThinAppViewCore && swift test)
(cd services/appview-worker && swift test)
(cd services/indexing-worker && swift test)
(cd packages/swift/OperationsCore && swift test)
(cd services/operations && swift test)
(cd services/jetstream-ingest && go test ./... && go vet ./...)

# iOS — Cmd+U in Xcode (see docs/test-plans/apple.md)

Architecture Principles

  • Protocol-first where data is portable: folders, publication preferences, subscriptions, and read-later records live on the user's own ATProto PDS
  • AppView-owned read state: feed read/unread state is local-first in clients and synchronized to Social Wire AppView for counters and unread filtering
  • Thin AppView read path: signed-in clients load bootstrap data, feeds, and entry detail through the gateway-backed AppView; standard.site bodies remain authoritative on publisher PDSes, while RSS feed bodies may be retained in the derived index (see docs/architecture/appview.md)
  • Disposable acceleration: projection/PDS caches, PLC coalescing, RSS leases, and reusable ranking sets can use Redis; PDS/Postgres remain authoritative. Development and Production currently select Redis, while Postgres cache tables remain the rollback backend (see docs/architecture/redis.md)
  • Direct ATProto where it fits: discovery and repo reads use public XRPC; Bluesky App View (public.api.bsky.app) for follows and profiles only
  • Interoperable by design: lexicons are public — any ATProto client can read a user's Social Wire folders

Deployment

Component Where
Web + Operations UI Railway
Gateway, AppView, Ingress Controller, Projection Pool, Coordinator Railway
Operations Railway
Database migrations Railway Database Migrator job
Durable index/state Railway Postgres (database/migrations/)
Optional disposable cache/coordination Private Railway Redis (currently selected in Development and Production)
CI/CD GitHub Actions validates source; Railway deploys through its Git integration

Charybdis retains the appview-worker directory, executable, and telemetry service key for migration rollback compatibility. See the replicated indexing design.

See docs/architecture/overview.md for the full architecture narrative.

Docs

License

This project is licensed under the MIT License — see LICENSE.

About

Monorepo for The Social Wire - An ATProto-based publication reader for the ATmosphere

Topics

Resources

Contributing

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages