WriteFreely

A clean, Markdown-based publishing platform for writers, with built-in ActivityPub federation for connecting to the wider fediverse.

5.3Kstars
GNU AGPLv3

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
87/100Excellent
Development Activity92
Maintenance84
Community72
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
63/100Good
Architecture60
Code Quality65
Innovation75
Learning Curve50

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.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search