Skip to content
 
 

Repository files navigation

easydocs

Git-style history for .docx — without asking anyone to learn Git.

CI Conformance Release License: AGPL-3.0

Open-source, self-hostable version control for Word documents. Every save becomes an immutable, numbered version. Two people editing at once branch instead of overwriting each other, and merge in one click. You get a real redline between any two versions even if nobody ever turned Track Changes on.

Two front doors: a web UI for the people who just need to work on the document, and a REST API for developers — the same surface, not a subset. One stack, docker compose up.

easydocs exists because Simuldocs, the hosted service this way of working lived in, shut down. This project is an independent reimplementation of that workflow — not affiliated with Simuldocs — built so the people who relied on it don't lose it. Self-hostable and AGPL-3.0 on purpose: those are exactly the guarantees a discontinued service can't take away.

Quickstart

Download the compose bundle from the latest release — no clone, no build, the image is pinned by version and signed with cosign:

mkdir easydocs && tar xzf easydocs-*-compose.tar.gz -C easydocs && cd easydocs
cp .env.example .env    # then edit it — two secrets, see below
docker compose up -d

Then open http://localhost:8080 and register. The first account you create also creates your organization, and you are its owner. Invite colleagues from Settings → Organization (or from a document's Members panel) and send them the invitation link; someone who belongs to more than one organization gets a switcher in the header.

From there, the User guide walks every screen and action — uploading, editing, branching and merging, publishing, approvals, sharing — and the API does everything the UI does.

Two things to set in .env:

  • Jwt__Secret ships deliberately too short to boot — the app fails fast under 32 bytes. Generate a real one with openssl rand -base64 48. (A placeholder that worked would mean every install that took the quickstart literally signed its sessions with a secret published in this repository.)
  • POSTGRES_PASSWORD — anything non-placeholder.

The stack is three containers: the app (with LibreOffice bundled for PDF rendering), PostgreSQL 16, and Collabora Online for in-browser editing.

⚠️ Plain HTTP beyond localhost silently breaks login. The session cookie is Secure, so a browser only sends it over HTTPS — or to localhost, which is why the quickstart works. Serve easydocs at http://192.168.1.50:8080 or http://easydocs.internal and login will appear to succeed, the browser will discard the cookie, and you land back on the sign-in screen with no error. Terminate TLS at a reverse proxy in front of the app — see the self-hosting guide.

Or hand it to an AI agent

Using Claude Code, Cursor, Copilot or any other coding agent? Paste this — it carries every footgun so the agent lands a working install on the first try:

Set up easydocs (https://github.com/Robertzu43/easydocs) on this machine. Docker must be running.

1. Download the easydocs-*-compose.tar.gz asset from the latest GitHub release
   (https://github.com/Robertzu43/easydocs/releases/latest) and extract it into a new
   directory called easydocs. Do NOT build from source.
2. In that directory: cp .env.example .env, then edit .env — set Jwt__Secret to the output
   of `openssl rand -base64 48` (the placeholder is deliberately too short to boot), and set
   POSTGRES_PASSWORD to a random value (update it in ConnectionStrings__Postgres too, where
   the same password appears).
3. Run `docker compose up -d`, then poll http://localhost:8080/health until it returns
   {"status":"ok"} (first boot pulls images and runs migrations — allow a few minutes).
4. Tell me to open http://localhost:8080 and register: the first account created also
   creates the organization and owns it. Point me at the user guide:
   https://robertzu43.github.io/easydocs/user-guide/
5. If this machine is a remote server rather than my laptop: STOP before exposing anything.
   The session cookie is Secure-only, so login silently fails over plain HTTP anywhere but
   localhost — TLS at a reverse proxy is required first, per
   https://robertzu43.github.io/easydocs/self-hosting/

Developing or building from source instead

git clone https://github.com/Robertzu43/easydocs && cd easydocs/deploy/compose
cp .env.example .env    # same two secrets
docker compose up --build

What it does

  • Every save is a version. Immutable, numbered X.Y.Z, attributed to an author, with a change summary. Nothing is ever silently overwritten.
  • Edit in the browser. Collabora Online via a WOPI host — no upload/download dance, no Word install.
  • Branch on stale, merge in one click. Two people editing the same version produce two branches rather than a lost edit. The console shows the branch indented under the main line with a Merge button, and the merge attributes the incoming author's changes.
  • Real redlines, Track Changes or not. Compare any two versions and get insertions and deletions computed from the documents themselves.
  • Publish, PDF, approve. Publish minor or major, get renumbering plus a rendered PDF, then request approval from named document members — one immutable decision each, cancellable while open.
  • Client copies with push-back review. Fork a version into an isolated copy with its own members and its own history. When the copy pushes work back, a member of the original reviews it: accept and it lands as a clearly-labelled incoming branch, reject and it never enters the history.
  • Share links. Version-scoped, expiring, revocable, and audited — an anonymous view lands on the audit trail with a view count. The recipient needs no account and sees a plain download page: no app chrome, no sign-up wall.
  • Folders, members, revert, trash, and an audit trail for every one of the above.

The whole lifecycle is doable in a browser without ever touching an HTTP client — which is what the Playwright suite asserts, against the shipped container image rather than a dev server.

New in v1.1

  • OIDC/SSO — point three env keys at any OpenID Connect provider and the login screen grows a "Sign in with SSO" entry. MFA — opt-in TOTP with single-use recovery codes, per account.
  • Desktop "Open in Word" — a version action hands desktop Word an ms-word: URL over WebDAV; saving in Word commits a new version through the same write path as everything else.
  • Full-text content search — the dashboard search box matches document content, not just names.
  • Graphical revision graph — a List/Graph toggle on the History tab.
  • S3-compatible blob storage, blob garbage collection, a durable job queue, and configurable trusted proxies — see the self-hosting guide.

Before exposing an install to anyone, read the known limitations in SECURITY.md — notably that per-IP rate limiting behind a reverse proxy needs ASPNETCORE_FORWARDEDHEADERS_ENABLED=true (and, since v1.1, ForwardedHeaders__KnownProxies__N to narrow the trust).

API

Everything the UI does, the API does — it is the same surface, not a subset.

  • Interactive docs: /docs on your install (self-contained, no external CDN)
  • OpenAPI 3.1: /openapi/v1.json
  • Auth: ed_-prefixed personal access tokens as Authorization: Bearer ed_…, or the session cookie for the browser. A token can never exceed the role of the user who minted it.
  • Live updates: server-sent events per document at /api/v1/documents/{id}/events.

Worked end-to-end examples: automation recipes.

Tech

ASP.NET Core (.NET 10) minimal APIs · PostgreSQL 16 · EF Core · React 19 + Vite 8 + react-router · Collabora Online (WOPI) · LibreOffice for PDF · content-addressed filesystem blobs. One container for the app; the SPA is built into it and served from wwwroot.

Docs

Guides are published at https://robertzu43.github.io/easydocs/:

And in the repo:

Feedback & contributing

If you try easydocs, say how it went — that's the most useful thing you can do for the project right now.

  • Something broke, or something's missing? Open an issue. "This felt wrong" is a valid report; describe the problem, not the solution.
  • Questions and ideas live in Discussions.
  • Want a roadmap item sooner? A 👍 or a "here's how I'd use it" comment on its issue is exactly the signal that decides ordering — see ROADMAP.md.
  • Want to write code? Start with CONTRIBUTING.md and the good first issue label. Schema and public-API changes need agreement in an issue first (GOVERNANCE.md); everything else, just open a PR.

easydocs exists because a closed service took a workflow down with it. It stays healthy the same way it started: people who need it, keeping it alive.

License

Everything in this repository today is AGPL-3.0 (LICENSE) — server, SPA, tests, deploy files, docs.

Path License
Everything in this repo AGPL-3.0 — the whole repository right now
packages/* — future API client SDKs MIT, when written. The directory does not exist yet.

AGPL is the right licence for a self-hostable server — it keeps modifications to a hosted easydocs available to its users. It is the wrong licence for a thin client library, so future SDKs will live under packages/* with their own MIT LICENSE. Until that directory exists, assume AGPL-3.0 for anything you take from here. Full reasoning: spec §14.

Contributions are under the Developer Certificate of Origin — sign off every commit with git commit -s. No CLA, and you keep the copyright to your contributions. Start with CONTRIBUTING.md; conduct is governed by the Code of Conduct (Contributor Covenant 2.1).

About

Git-style version control for Word documents — self-hostable, in-browser editing via Collabora, one-click branch & merge, real redlines without Track Changes. AGPL-3.0.

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages