WriteFreely
A clean, Markdown-based publishing platform for writers, with built-in ActivityPub federation for connecting to the wider fediverse.
Repository Health
Technical Analysis
WriteFreely is a minimalist, open-source blogging platform built in Go, designed around a distraction-free writing experience. Posts are written in Markdown through an auto-saving editor, and the platform strips away comment threads, follower counts, and other typical blog cruft in favor of a plain, readable design. It powers Write.as, the hosted service run by the same team, and has been running in production as one of the earliest ActivityPub-native publishing platforms.
The platform ships as a single static Go binary that works with SQLite out of the box or against MySQL/MariaDB for larger deployments, so self-hosting requires no separate application server. Multi-user instances support per-user blogs, drafts, static “pinned” pages, and hashtag-based categorization, while a single-user mode turns the same binary into a lightweight personal blog.
Federation is a first-class feature: every blog on a WriteFreely instance can be followed from Mastodon, Plume, and other ActivityPub software, and instances can onboard existing users through OAuth 2.0 account linking. Combined with support for 20+ localized languages and RTL scripts, plus Web Monetization payment pointers for tipping, WriteFreely positions itself as a privacy-respecting alternative to centralized blogging platforms like Medium or Substack.
What You Get
- Distraction-free Markdown editor with auto-save
- Native ActivityPub federation for follows and replies from Mastodon and other fediverse apps
- Single static Go binary with a built-in SQLite backend or optional MySQL/MariaDB
- Multi-user and single-user deployment modes from the same codebase
- OAuth 2.0 login via Slack, GitLab, Gitea, Write.as, or a generic provider
- RSS/Atom feeds, sitemaps, webfinger, and nodeinfo endpoints for federation discovery
Common Use Cases
- Hosting a personal, ad-free blog on your own domain
- Running a small community or organization’s group blog with multiple contributor accounts
- Publishing pseudonymous or pen-name writing without linking accounts publicly
- Standing up a fediverse-connected publishing instance that federates with Mastodon
- Creating static informational pages (about, contact) by pinning posts to a blog
Under The Hood
Architecture
WriteFreely is a monolithic Go web application centered on an App struct (app.go) that directly holds the router (gorilla/mux), datastore, config, key chain, and session store rather than wiring dependencies through a DI container. Routes are registered in routes.go through handler.Web/handler.User middleware wrappers that enforce per-route user levels, while the data layer lives largely in a single large database.go file alongside a hand-rolled SQL dialect abstraction in the db/ package (dialect.go, create.go, alter.go) that generates equivalent DDL for both SQLite and MySQL so the same migrations work across backends. ActivityPub federation is implemented in a substantial activitypub.go that layers directly on top of collection visibility checks (IsPrivate/IsProtected in collections.go), which are threaded consistently through posts.go, feed.go, and activitypub.go — making that visibility abstraction the load-bearing invariant that would ripple across every layer if it changed. Separation of concerns beyond this is achieved mostly through small focused packages (author/, config/, db/, key/, oauth/, page/) rather than internal layering within the core package.
Tech Stack The stack is idiomatic Go with gorilla/mux for routing, gorilla/sessions and gorilla/csrf for session and CSRF handling, and gorilla/schema for form decoding, all backed by database/sql with go-sql-driver/mysql and mattn/go-sqlite3 rather than an ORM. Federation depends on writeas/activity and writeas/httpsig for signed ActivityPub requests plus go-webfinger and go-nodeinfo for discovery, while shared internal libraries from the same maintainers (writeas/web-core, writeas/impart) provide auth helpers, converters, and HTTP error handling. OAuth 2.0 support for Slack, GitLab, Gitea, Write.as, and generic providers is hand-implemented per provider rather than through a single generic OAuth2 client library. The project builds and ships as a static binary via a Makefile, with Dockerfile/Dockerfile.prod and docker-compose for containerized deployment.
Code Quality
The repo includes a reasonable spread of test files (database_test.go, oauth_test.go, posts_test.go, signup_test.go, template_render_test.go, activitypub_test.go, and others) using stretchr/testify, with main_test.go conditionally running integration tests against a real MySQL instance via environment variables alongside default SQLite-backed unit tests — a fairly thorough dual-backend testing setup for a project this size. Error handling follows idiomatic Go conventions with explicit (value, error) returns wrapped through the impart package, and naming is consistently idiomatic Go. Visible CI is limited to a Docker image publish workflow, with no dedicated automated lint or test workflow apparent in the current GitHub Actions configuration, and a legacy Travis config remains from before the migration off Travis CI.
What Makes It Unique WriteFreely treats ActivityPub federation as a first-class, built-in property of a blogging engine rather than an optional plugin: every blog is independently discoverable and followable from Mastodon or other fediverse software through native webfinger and nodeinfo support, which is unusual among self-hosted publishing platforms that typically require an add-on for federation. It also natively supports Web Monetization payment pointers for streaming micropayments to writers, a standard most blogging competitors don’t implement at all. Paired with a single-binary, embedded-SQLite deployment model shared with the broader Write.as ecosystem, this keeps a federated publishing service unusually simple to operate.
Self-Hosting
Licensing Model AGPL-3.0 licensed — all features, including federation and multi-user support, are available in self-hosted deployments with no license keys or paid tiers.
Self-Hosting Restrictions
None found — there is no ee/, enterprise/, or pro/ directory, and no license-check or feature-flag gating in the source that restricts functionality for self-hosters.
Enterprise Features None — there is no separate enterprise or paid tier in the codebase; the only official commercial option is the fully-managed Write.as hosting service run by the maintainers.
Cloud vs Self-Hosted Write.as (the hosted offering) provides managed installation, backups, and upgrades on top of the identical open-source codebase — it does not unlock additional features over self-hosting.
License Key Required No.
Related Apps
OpenCut
Design Tools · Social Media · Video Editors
Free, open-source video editor for web, desktop, and mobile — no watermarks, no subscriptions, built with a Rust core and plugin-first architecture
Ghost
CMS · Blogging
Open source headless Node.js CMS for professional publishing, paid memberships, and newsletters with a fully owned audience.
Mastodon
Social Media
Run your own federated social network on the open ActivityPub standard with no ads, no algorithms, and no corporate control over your community.