A complete location-based social feed generator and web interface built on the AT Protocol for decentralized social networking. Provides both API endpoints for mobile clients and a web interface for viewing and sharing check-ins.
PDS-Only Architecture: This system does NOT store checkin data locally. All checkins are:
com.atproto.repo.createRecordcom.atproto.repo.getRecord and
com.atproto.repo.listRecordsThe system consists of 4 main components:
backend/
āāā oauth/ # OAuth authentication and session management
ā āāā storage.ts # Drizzle storage adapter for OAuth sessions
āāā routes/ # Hono route handlers
ā āāā oauth.ts # OAuth configuration and endpoints
āāā api/ # HTTP API endpoints
ā āāā anchor-api.ts # Main feed API (reads from PDS)
ā āāā checkins.ts # Check-in creation API with image upload
āāā services/ # Business logic services
ā āāā image-service.ts # Image validation (magic numbers) and processing
ā āāā overpass-service.ts # Address enrichment via OpenStreetMap
āāā database/ # Database layer (OAuth sessions only)
āāā db.ts # Drizzle ORM setup with sqlite-proxy
āāā schema.ts # Database schema (iron_session_storage)
āāā migrations.ts # Table creation and migrations
frontend/
āāā main.tsx # Entry point and routing
āāā components/ # React components
ā āāā CheckinComposer.tsx # Create checkin with image picker
ā āāā CheckinCard.tsx # Feed card with square thumbnail
ā āāā CheckinDetail.tsx # Detail view with full-size image and map
ā āāā ImageLightbox.tsx # Full-screen image viewer with alt text
ā āāā Layout.tsx # App layout and navigation
āāā types/
āāā index.ts # TypeScript type definitions
lexicons/ # AT Protocol lexicon definitions
āāā app/dropanchor/
āāā checkin.json # Checkin record schema with embedded address, geo, image
docs/
āāā api-documentation.md # Complete API reference for client development
āāā deployment-guide.md # Deployment instructions
scripts/
āāā test.sh # Run complete test suite
āāā debug-oauth-sessions.ts # Debug OAuth session status
āāā publish-lexicons.ts # Publish lexicons to PDS as AT Protocol records
tests/
āāā unit/ # Unit tests for individual functions
ā āāā image-service.test.ts # Image validation with magic numbers
ā āāā lexicon-validation.test.ts # Lexicon structure validation
ā āāā spatial.test.ts
āāā integration/ # Integration tests for API endpoints
ā āāā api.test.ts # Feed APIs
ā āāā checkin-api.test.ts # Checkin creation with image upload
āāā fixtures/ # Test data and fixtures
āāā test-data.ts
deno task deploy # Runs quality checks and pushes to Val Town
Note: No manual database setup required! Tables are created automatically when functions first run.
Base URL: https://dropanchor.app
GET https://dropanchor.app/api/nearby?lat=52.0705&lng=4.3007&radius=5&limit=50
Spatial query for check-ins within specified radius (km).
GET https://dropanchor.app/api/user?did=did:plc:abc123&limit=50
All check-ins from a specific user.
GET https://dropanchor.app/api/following?user=did:plc:abc123&limit=50&cursor=2025-06-29T15:00:00Z
Check-ins from people the specified user follows on Bluesky.
GET https://dropanchor.app/api/checkin/{rkey}
Individual checkin data by record key for detail views and sharing.
GET https://dropanchor.app/api/stats
AppView health metrics and processing statistics.
https://dropanchor.app/
Web interface showing user feeds and check-ins.
https://dropanchor.app/checkin/{rkey}
Individual checkin detail page with interactive map, optimized for sharing on social media with Open Graph meta tags.
For complete API documentation including examples, data models, and SDK code samples, see:
For developers integrating with Anchor's authentication system:
š Authentication Guide - Anchor-specific setup guide:
š± Mobile OAuth Guide - Complete OAuth implementation (in package docs):
PDS-Only Design: No local checkin storage. All checkin data lives in users' Personal Data Servers.
Local Storage: Only iron_session_storage table for OAuth session
management (encrypted with Iron Session).
AT Protocol Records:
app.dropanchor.checkin - Checkin with embedded address, geo coordinates, and
optional image attachment. All location data is self-contained within the
checkin record.Image Storage: Blobs uploaded to user's PDS via
com.atproto.repo.uploadBlob, retrieved via com.atproto.sync.getBlob.
@tijs/atproto-oauthThe project includes comprehensive tests for all components (142 tests):
Unit Tests:
image-service.test.ts - Image validation with magic number detectionlexicon-validation.test.ts - Lexicon structure and backward compatibilityspatial.test.ts - Spatial distance calculationsIntegration Tests:
checkin-api.test.ts - Checkin creation with image upload (multipart form
data)api.test.ts - Feed APIs and PDS integration# Run all tests deno task test # or ./scripts/test.sh # Run specific test suites deno task test:unit # Unit tests only deno task test:integration # Integration tests only # Watch mode for TDD deno task test:watch # Quality checks (format, lint, type check, test) deno task quality
import { sqlite } from "https://esm.town/v/std/sqlite2"
sqlite2, not sqlite (deprecated)await sqlite.execute({ sql: "...", args: [...] })https://esm.sh for npm packages, jsr: for JSR packagesDeno.env.get('keyname')iron_session_storage)com.atproto.repo.createRecord for writes,
com.atproto.repo.getRecord/listRecords for readsuploadBlob, served via getBlob/api/stats endpoint for system healthscripts/debug-oauth-sessions.ts to inspect OAuth session statusDeno.env.get()The AppView is fully compatible with the AT Protocol ecosystem:
app.dropanchor.checkin with embedded address and geo
objects@tijs/atproto-oauth with PKCE flow and DPoPLexicons are published as com.atproto.lexicon.schema records following the
official AT Protocol spec:
| Lexicon | AT-URI |
|---|---|
app.dropanchor.checkin | at://did:plc:aq7owa5y7ndc2hzjz37wy7ma/com.atproto.lexicon.schema/app.dropanchor.checkin |
app.dropanchor.like | at://did:plc:aq7owa5y7ndc2hzjz37wy7ma/com.atproto.lexicon.schema/app.dropanchor.like |
app.dropanchor.comment | at://did:plc:aq7owa5y7ndc2hzjz37wy7ma/com.atproto.lexicon.schema/app.dropanchor.comment |
Resolution chain: app.dropanchor.* ā DNS TXT _lexicon.dropanchor.app ā
did:plc:aq7owa5y7ndc2hzjz37wy7ma ā PDS (hamster.farm) ā schema records.
See docs/lexicon-publishing.md for details on updating lexicons.
Static images are hosted on Bunny CDN at cdn.dropanchor.app:
https://cdn.dropanchor.app/images/anchor-logo.png - App logohttps://cdn.dropanchor.app/images/seagull-looking.png - Empty statehttps://cdn.dropanchor.app/images/seagull-chest.png - Login promptIf you find this project useful and would like to support its development, you can buy me a coffee on Ko-fi.
This implementation is part of the Anchor project for location-based social networking on the AT Protocol.