Skip to content
STACK IT FAST

Lemmy

Curated OSSClassicFederated Link Aggregator & Forum20+ people

Audited from github.com/LemmyNet/lemmy

Lemmy is a decentralised, federated link aggregator and forum similar to Reddit, with a Rust backend on Actix Web, PostgreSQL through Diesel, and ActivityPub federation between independently run instances.

Language
Rust
Database
PostgreSQL
Hosting
Docker
License
AGPL-3.0
Running for
7 years
Team
20+ people

Why this architecture

Lemmy splits its Rust backend into many small crates (per database view, API, ActivityPub, email) over one PostgreSQL schema with heavy migrations, so federation, the local API and queries evolve separately while a single binary serves an instance.

Tech stack by layer

11 technologies · audited Oct 2, 2026
Backend & APIs
  • RustBackend language for the lemmy_server binary and all workspace crates (edition 2024, Rust 1.92 minimum).
  • Actix-webHTTP server for the API, RSS feeds and federation endpoints, with actix-cors, rate limiting and tracing middleware.
  • ActivityPubFederation with other instances through the activitypub_federation crate in the crates/apub/* crates.
  • LettreSMTP email with pooled rustls connections; templates are translated with rosetta-i18n.
  • markdown-itRenders user Markdown with plugins for spoilers, sub/superscript and ruby text.
Data & Persistence
  • PostgreSQLOnly database; migrations directory holds hundreds of timestamped Diesel migrations, many in PL/pgSQL.
  • DieselORM and query builder (diesel and diesel-async), with diesel_ltree for comment trees and per-view crates in crates/db_views.
  • MokaIn-process cache used by the schema and utils crates.
Infrastructure & Deploy
  • DockerMulti-stage build with cargo-chef layer caching, Debian runner, non-root user, port 8536.
  • NginxReverse proxy configuration shipped for the Docker Compose deployment.
  • PrometheusMetrics exported through actix-web-prom and the prometheus crate in the routes crate.
  • Woodpecker CICI pipeline defined in .woodpecker.yml; no GitHub Actions workflows are present.
  • JestTypeScript API and federation tests in api_tests/ that run several Lemmy instances against each other.

Lemmy architecture diagram

Open SVG
Lemmy architecture diagramWeb and mobile clients → Reverse proxy (HTTPS); Other instances → Reverse proxy (inbox); Reverse proxy → lemmy_server; lemmy_server → Database (Diesel); lemmy_server → Federation send (activities); Federation send → Other instances (deliver); lemmy_server → Email (notify)CLIENTSSERVICESWORKERS & JOBSDATA & STORAGEEXTERNALWeb and mobile clientsHTTP APIOther instancesActivityPubReverse proxyNginxlemmy_serverRust · Actix WebFederation sendactivitypub_federationDatabasePostgreSQL · DieselEmailSMTP · LettreHTTPSinboxactivitiesDieseldelivernotify
How the main components of Lemmy connect, drawn from the audited repository.
Diagram as text
  • Web and mobile clients (HTTP API) → Reverse proxy (Nginx): HTTPS
  • Other instances (ActivityPub) → Reverse proxy (Nginx): inbox
  • Reverse proxy (Nginx) → lemmy_server (Rust · Actix Web)
  • lemmy_server (Rust · Actix Web) → Database (PostgreSQL · Diesel): Diesel
  • lemmy_server (Rust · Actix Web) → Federation send (activitypub_federation): activities
  • Federation send (activitypub_federation) → Other instances (ActivityPub): deliver
  • lemmy_server (Rust · Actix Web) → Email (SMTP · Lettre): notify

Key architectural decisions

5 decisions
  1. 01

    Dozens of small crates, one per database view

    The workspace in Cargo.toml lists crates/db_views/post, comment, community, person, notification, modlog, report_combined and many more as separate crates next to db_schema, api, apub and routes, so a change to one query view recompiles only the crates that depend on it.

  2. 02

    Federation as its own crate family

    crates/apub/apub, activities, objects and send isolate ActivityPub handling, built on the activitypub_federation crate that crates/server also depends on, so inbound activities, object conversion and outbound delivery are separated from the local API.

  3. 03

    PostgreSQL does real work through migrations

    migrations/ contains hundreds of timestamped Diesel migrations from 2019 onwards and PL/pgSQL is the second-largest language in the repository, so counters, triggers and tree logic live in the database; diesel_ltree supports comment trees.

  4. 04

    TypeScript types generated from Rust structs

    Crates such as db_schema, routes and utils expose a ts-rs feature, which derives TypeScript definitions from the Rust API types for client libraries, keeping the API contract in one place.

  5. 05

    Two API generations served side by side

    crates/api/routes and crates/api/routes_v3 are separate workspace members wired into lemmy_server, so older clients keep working on the v3 routes while the current API evolves.

How Lemmy is built

How Lemmy is structured

This repository is the Lemmy backend. The web UI is not part of the source tree. The root Cargo.toml declares a large workspace (version 1.0.0-beta.2, edition 2024) whose crates fall into a few families:

Path Role
crates/server The lemmy_server binary that wires everything together
crates/api/* api, api_crud, api_common, api_utils, plus routes and routes_v3 for two API generations
crates/apub/* ActivityPub federation: apub, activities, objects, send
crates/db_schema, db_schema_file, diesel_utils Diesel schema, models and helpers
crates/db_views/* One crate per read model: posts, comments, communities, notifications, modlog, reports and more
crates/routes Non-API HTTP: RSS feeds, Prometheus metrics, local image routes
crates/email, crates/utils Email delivery and shared utilities (config, Markdown, rate limiting)
migrations/ Hundreds of timestamped Diesel migrations
api_tests/ TypeScript and Jest API and federation tests
docker/ Dockerfile, Compose file, Nginx and PostgreSQL configs, deploy scripts

Backend & APIs

The server runs on Actix Web. crates/server/Cargo.toml pulls in actix-web, tracing-actix-web, reqwest-middleware with reqwest-tracing for outbound calls, and clap for the CLI. On x86_64 it uses tikv-jemallocator as the allocator. crates/routes adds actix-cors, actix-web-prom (Prometheus metrics), the rss crate for feeds and clokwerk for scheduled jobs. crates/utils holds rate limiting (actix-extensible-rate-limit), Hjson config parsing (deser-hjson), markdown-it rendering with spoiler, sub, sup and ruby plugins, and clearurls to strip tracking parameters from links.

Two API generations live side by side, crates/api/routes and crates/api/routes_v3. A ts-rs feature on several crates generates TypeScript types from Rust structs for client libraries.

Data & persistence

PostgreSQL is the only store, accessed with Diesel and diesel-async (crates/db_schema/Cargo.toml). diesel_ltree models comment trees, diesel-uplete handles combined update-or-delete operations, and moka caches hot data in process. PL/pgSQL is the repository's second-largest language: migrations/ goes back to 2019, and much counting and trigger logic lives in the database rather than in Rust. Read paths are split into many crates/db_views/* crates, each owning the queries for one view.

Realtime / collaboration

Federation is the "realtime" layer. The crates/apub/* crates use the activitypub_federation crate to receive activities in an inbox, turn them into local objects and deliver outgoing activities to followers on other instances. api_tests/run-federation-test.sh and prepare-drone-federation-test.sh start several instances and test federation end to end.

Build, test & deploy

  • CI runs on Woodpecker (.woodpecker.yml). There are no GitHub Actions workflows.
  • docker/Dockerfile uses cargo-chef to cache dependency builds, builds lemmy_server in release or debug mode, and runs it as a non-root user on a slim Debian image, exposing port 8536.
  • The release profile uses lto = "fat" and codegen-units = 1. The dev profile drops debug info for faster builds.
  • cliff.toml generates changelogs with git-cliff.

Self-hosting notes

docker/ contains everything for a Compose deployment: docker-compose.yml, nginx.conf as the reverse proxy, customPostgresql.conf for tuning, lemmy.hjson for instance config, and docker_db_backup.sh and docker_update.sh for operations. Configuration defaults are documented in config/defaults.hjson.

What to copy (and what not to)

Copy:

  • One crate per read model (db_views/*), which keeps compile times and ownership manageable in a large Diesel codebase.
  • Federation isolated in its own crates, so protocol changes do not ripple through the local API.
  • Generate client types from server structs (ts-rs) instead of maintaining them by hand.
  • Ship the operational scripts (backup, update, proxy config) with the code.

Don't copy blindly:

  • Putting much logic in PL/pgSQL triggers is fast but harder to test and review than Rust.
  • Dozens of workspace crates suit a long-lived project. A new app should start with a few and split when compile times demand it.

For an Actix-based stack compared with Axum, see Actix Web and Axum.

Sources & repo audit

Audited
Oct 2, 2026
Commit
8d83bcf
License
AGPL-3.0

Independent analysis of repository at github.com/LemmyNet/lemmy. Spotted an inaccuracy? Use the claim form to request a correction.

Maintainer? Add the architecture badge to your README
architecture: stackitfast
[![Architecture on STACK IT FAST](https://stackitfast.com/badge/lemmy.svg)](https://stackitfast.com/project/lemmy)
Use this stack

Scaffold it with your agent

Paste this prompt into Claude Code, Cursor, Windsurf or AGY to start a project with Lemmy's architecture.

  1. 1Copy the promptThe full markdown spec, with every layer and decision.
  2. 2Open your AI toolClaude Code, Cursor, Windsurf or Copilot, in a new repo.
  3. 3Paste and scaffoldUse it as the first instruction; review before you ship.
use-this-stack.md · 58 lines · 6.9 KB
# MISSION: Scaffold "Lemmy" Production Architecture
You are an expert Senior Staff Software Architect and Full-Stack Engineer. Your mission is to scaffold and implement a production-grade, highly reliable, and modular codebase following the proven architecture of **Lemmy**.
---
## 1. PROJECT SPECIFICATIONS & BENCHMARK
- **Reference Architecture**: Lemmy
- **What It Does**: Lemmy is a decentralised, federated link aggregator and forum similar to Reddit, with a Rust backend on Actix Web, PostgreSQL through Diesel, and ActivityPub federation between independently run instances.
- **Domain & Category**: Federated Link Aggregator & Forum
- **Production Scale**: 20+ people
- **Development Mode**: CLASSIC
- **Architectural Rationale**: Lemmy splits its Rust backend into many small crates (per database view, API, ActivityPub, email) over one PostgreSQL schema with heavy migrations, so federation, the local API and queries evolve separately while a single binary serves an instance.
- **Live Website Reference**: https://join-lemmy.org
- **Source Repository**: https://github.com/LemmyNet/lemmy
---
## 2. PRODUCTION TECH STACK
- **Full Stack Array**: Rust, Actix-web, Diesel, PostgreSQL, ActivityPub, Tokio, Prometheus, Docker, Nginx, TypeScript, Jest
- **Primary Language(s)**: Rust, PLpgSQL, TypeScript
- **License of the reference repo**: AGPL-3.0
- **Backend & APIs**: Rust — Backend language for the lemmy_server binary and all workspace crates (edition 2024, Rust 1.92 minimum).; Actix-web — HTTP server for the API, RSS feeds and federation endpoints, with actix-cors, rate limiting and tracing middleware.; ActivityPub — Federation with other instances through the activitypub_federation crate in the crates/apub/* crates.; Lettre — SMTP email with pooled rustls connections; templates are translated with rosetta-i18n.; markdown-it — Renders user Markdown with plugins for spoilers, sub/superscript and ruby text.
- **Data & persistence**: PostgreSQL — Only database; migrations directory holds hundreds of timestamped Diesel migrations, many in PL/pgSQL.; Diesel — ORM and query builder (diesel and diesel-async), with diesel_ltree for comment trees and per-view crates in crates/db_views.; Moka — In-process cache used by the schema and utils crates.
- **Infrastructure & deploy**: Docker — Multi-stage build with cargo-chef layer caching, Debian runner, non-root user, port 8536.; Nginx — Reverse proxy configuration shipped for the Docker Compose deployment.; Prometheus — Metrics exported through actix-web-prom and the prometheus crate in the routes crate.; Woodpecker CI — CI pipeline defined in .woodpecker.yml; no GitHub Actions workflows are present.; Jest — TypeScript API and federation tests in api_tests/ that run several Lemmy instances against each other.
---
## 3. KEY ARCHITECTURAL DECISIONS (audited from https://github.com/LemmyNet/lemmy @ 8d83bcf)
1. **Dozens of small crates, one per database view**: The workspace in Cargo.toml lists crates/db_views/post, comment, community, person, notification, modlog, report_combined and many more as separate crates next to db_schema, api, apub and routes, so a change to one query view recompiles only the crates that depend on it.
2. **Federation as its own crate family**: crates/apub/apub, activities, objects and send isolate ActivityPub handling, built on the activitypub_federation crate that crates/server also depends on, so inbound activities, object conversion and outbound delivery are separated from the local API.
3. **PostgreSQL does real work through migrations**: migrations/ contains hundreds of timestamped Diesel migrations from 2019 onwards and PL/pgSQL is the second-largest language in the repository, so counters, triggers and tree logic live in the database; diesel_ltree supports comment trees.
4. **TypeScript types generated from Rust structs**: Crates such as db_schema, routes and utils expose a ts-rs feature, which derives TypeScript definitions from the Rust API types for client libraries, keeping the API contract in one place.
5. **Two API generations served side by side**: crates/api/routes and crates/api/routes_v3 are separate workspace members wired into lemmy_server, so older clients keep working on the v3 routes while the current API evolves.
---
## 4. NON-NEGOTIABLE ARCHITECTURAL GUARDRAILS
1. **Monorepo & Modular Separation**:
   - Structure as a Turborepo monorepo with strict package boundaries:
     - `apps/web`: Application UI, routing, layouts, and server endpoints.
     - `packages/ui`: Shared design tokens, CSS variables, and Radix UI primitive components.
     - `packages/db`: Database schemas, client singleton, declarative migrations, and seed scripts.
     - `packages/config`: Shared TypeScript, ESLint, and build configurations.
2. **Strict Type Safety & Zero `any` Policy**:
   - Enable `strict: true`, `noImplicitAny: true`, and `strictNullChecks: true`.
   - Validate ALL external inputs, API request bodies, and query parameters with **Zod** schemas before execution.
3. **Frontend & Rendering Guidelines**:
   - Isolate interactive UI state to leaf components. Keep core pages lightweight and performant.
4. **Design System & Aesthetics**:
   - Keep every color, radius, shadow and font in a single token file (CSS variables) and consume tokens everywhere; never hardcode hex values in components.
   - Prefer crisp 1px borders and one subtle shadow scale over blurry default shadows. Pair one sans-serif for body/headings with one monospace for tags, badges, metrics, and code.
5. **Data Layer & Reliability**:
   - Write declarative schema definitions with foreign keys, composite indexes on queried filters, and automated timestamp triggers.
   - Use connection pooling and prepared statements for serverless database execution.
---
## 5. STEP-BY-STEP SCAFFOLDING ROADMAP
- **Phase 1: Workspace & Root Config**: Initialize package manager, monorepo configuration (`turbo.json`, `tsconfig.base.json`, `package.json`).
- **Phase 2: Database Schema & Client**: Set up the data layer (PostgreSQL, Diesel, Moka): client, connection pool, models, and migration scripts.
- **Phase 3: Design Tokens & UI Primitives**: Build accessible `Button`, `Input`, `Card`, `Badge`, and layout wrappers inside `packages/ui`.
- **Phase 4: Core Application Routes & Handlers**: Implement primary authentication, user session handling, and application routes.
- **Phase 5: Quality Assurance & Build Verification**: Run `tsc --noEmit`, ESLint, Prettier, and smoke test suites to ensure zero compilation or runtime errors.
---
## 6. EXECUTION INSTRUCTIONS
1. Review all specifications, architectural guardrails, and stack choices above.
2. Present the full monorepo directory tree structure.
3. Systematically generate the complete, production-ready codebase according to the 5-phase roadmap above — starting with the root workspace setup, followed by the database schema, UI design system package, and full-stack application routes until the repository is fully scaffolded and ready to run.
Scaffolded something with this prompt?
Would you pick this stack for a federated link aggregator & forum project?

Frequently asked about Lemmy

What is Lemmy written in?

The Lemmy backend is written in Rust on Actix Web, with Diesel and diesel-async for PostgreSQL and the activitypub_federation crate for federation. TypeScript in the repository is used for API and federation tests in api_tests/.

What database does Lemmy use?

PostgreSQL only. The repository carries hundreds of Diesel migrations since 2019, many written in PL/pgSQL, and uses the ltree extension through diesel_ltree for comment trees.

How does Lemmy federate with other servers?

Through ActivityPub. The crates/apub crates (apub, activities, objects, send) receive activities from other instances, convert them into local objects and deliver outgoing activities, built on the activitypub_federation crate.

How do I self-host Lemmy?

The repository ships a docker/ directory with a Dockerfile, docker-compose.yml, an Nginx config, a custom PostgreSQL config, a lemmy.hjson config and backup and update scripts. The server image listens on port 8536.

Does Lemmy use Actix or Axum?

Actix Web. lemmy_server and lemmy_routes depend on actix-web with actix-cors, actix-web-prom for Prometheus metrics, tracing-actix-web and actix-extensible-rate-limit.

One email a month: new deep dives and stack trends

New source-audited architectures, head-to-head comparisons and the monthly stack report. No spam, unsubscribe anytime.

use-this-stack.md