Write on the margins of the internet. Powered by the AT Protocol. margin.at
extension web atproto comments
JavaScript 60.6%
Fluent 16.4%
TypeScript 10.8%
Go 6.2%
CSS 4.5%
HTML 1.2%
Astro 0.2%
Shell 0.1%
Dockerfile 0.1%
Other 0.1%
208 3 24

Clone this repository

https://tangled.org/margin.at/margin
git@tangled.org:margin.at/margin

For self-hosted knots, clone URLs may differ based on your setup.

README.md

Margin#

Write in the margins of the web

A web annotation layer built on AT Protocol that lets you annotate, highlight, and bookmark any URL on the internet.

Project Structure#

margin/
├── lexicons/           # AT Protocol lexicon schemas
│   └── at/margin/
│       ├── annotation.json
│       ├── bookmark.json
│       ├── collection.json
│       ├── collectionItem.json
│       ├── highlight.json
│       ├── like.json
│       ├── reply.json
│       ├── apikey.json
│       ├── preferences.json
│       └── profile.json
├── backend/            # Go API server
│   ├── cmd/server/
│   └── internal/
├── web/                # Astro SSR + React web app
│   └── src/
├── extension/          # Browser extension (WXT)
│   └── src/
└── avatar/             # Cloudflare Worker for avatar proxying

Getting Started#

Run the full stack with Docker:

docker compose up -d --build

This builds both the Go backend and the Astro frontend into a single container. The Astro SSR server handles all frontend routing, static assets, and OG image generation, while the Go backend serves the API internally.

Development#

Backend#

cd backend
go mod tidy
go run ./cmd/server

API server runs on http://localhost:8081

Web App#

cd web
bun install
bun run dev

Dev server runs on http://localhost:4321 and proxies API requests to the backend.

Browser Extension#

Built with WXT:

cd extension
bun install
bun run dev          # Chrome dev mode
bun run dev:firefox  # Firefox dev mode

Architecture#

In production, a single Docker container runs both services:

  • Astro SSR (port 8080, public) — serves the web app, handles SSR for OG meta tags, generates dynamic OG images via satori, and proxies API/auth requests to the backend.
  • Go API (port 8081, internal) — handles all API endpoints, OAuth, firehose ingestion, and data storage.

Domain#

Domain: margin.at Lexicon Namespace: at.margin.*

Tech Stack#

  • Backend: Go + Chi + SQLite
  • Frontend: Astro 5 (SSR) + React 19 + Tailwind CSS
  • OG Images: satori + @resvg/resvg-js
  • Extension: WXT + React + Tailwind CSS
  • Protocol: AT Protocol (Bluesky)

License#

MIT