A collaborative Markdown editor where several people type in the same document at once and the rendered result is a shareable URL. It replaces HackMD's hosted service and the pattern of passing a Google Doc around for meeting notes.
Our verdict on HedgeDoc#
HedgeDoc 1.x works well and has one uncomfortable fact attached. HedgeDoc 2 has been in development since 2020, shipped its first alpha in October 2023, and as of September 2026 is still unreleased with roughly 50 issues open against 462 closed on the 2.0 milestone. Meanwhile 1.x keeps getting real maintenance: 1.12.0 landed in August 2026, fixed realtime connection bugs that caused data loss on flaky links, and raised the floor to Node 20.17. So you are running a codebase the maintainers regard as the old one, on a rewrite timeline nobody will commit to, with no migration tool written yet because 2.0 has not shipped. If you want scratch pads for meetings and lectures that anyone can open with a link, that risk is acceptable and nothing else in this list does live Markdown co-editing as cleanly. If you want a permanent documentation home, use BookStack instead.
Who HedgeDoc is for#
Choose it if
- Meeting notes, lecture notes and workshop agendas where several people type at once and nobody wants an account
- Clubs, university groups and hackerspaces replacing a hosted HackMD instance
- Anyone who wants Markdown-in, HTML-out with slide mode and diagrams from the same source
- Operators who want a two container stack and a backup that is a pg_dump plus one directory
Look elsewhere if
- You need a durable long-lived knowledge base with hierarchy and permissions; pads are flat and disposable by design
- The 2.0 rewrite risk matters to you, since no 1.x to 2.x migration path has shipped after six years
- You want the newest editor experience, because the 1.x frontend is visibly of its era
What running it actually looks like#
Two containers: quay.io/hedgedoc/hedgedoc on port 3000 and PostgreSQL, with official images for amd64 and arm64. The variable that decides whether the install works is CMD_DOMAIN, which takes just the hostname with no protocol or path; the docs warn your instance may be broken if it does not match how people reach it. Pair it with CMD_PROTOCOL_USESSL=true and CMD_URL_ADDPORT=false behind a TLS proxy on standard ports. Mount a volume at /hedgedoc/public/uploads for images. Do not upgrade PostgreSQL by editing the version tag; the compose file warns you must migrate the database first. Upgrades of HedgeDoc itself are a tag bump, but read the release notes, since 1.12.0 raised the Node floor and removed some highlight.js languages.
Resource profile#
- Memory
- 250 MB idle, around 480 MB in ordinary use. Estimate for the Node app plus PostgreSQL at rest. Each open pad holds its collaborative document state in the Node process, so memory tracks concurrently open notes rather than total notes stored.
- CPU and acceleration
- Low except during editing. Every keystroke in a shared pad is an operational transform broadcast over websockets, so a lecture hall of forty simultaneous editors on one pad is the load case, not the size of your archive.
- Storage growth
- Note text and revisions live in the database and stay small. Uploaded images default to the filesystem under `public/uploads`, which is the directory that actually grows.
- Operational load
- 2 of 5, Light. Two containers, a straightforward Postgres dump plus an uploads directory for backup, and 1.x upgrades that are a tag bump. The open question is the eventual 1.x to 2.x migration, which does not exist yet.
Figures describe a small single-household install and are the working assumptions behind our stack planner. Your numbers will differ with library size, user count and hardware. See methodology.
Data and backup surface#
A pg_dump of the database plus the uploads volume. Notes, revisions, users and permissions are all rows; images uploaded with the default filesystem upload type are files under public/uploads and nothing in the dump references their content. A live copy of the uploads directory is safe because uploads are immutable, but the database wants a proper dump rather than a file copy of the Postgres data directory. Redis is not used. If you switched CMD_IMAGE_UPLOAD_TYPE to s3, minio or azure, the uploads volume is empty and your bucket is now part of the backup set instead.
Derived backup shape
Postgres dump. pg_dump (or pg_dumpall) into a file, then snapshot that file plus the app's data volume.
Traps and surprises#
Anonymous access is on by default
CMD_ALLOW_ANONYMOUS defaults to true and CMD_ALLOW_EMAIL_REGISTER also defaults to true. Put a fresh instance on the public internet and anyone can create notes and register an account. Set both to false and create users with bin/manage_users if you want a closed instance, and set CMD_DEFAULT_PERMISSION (default editable) to match your intent.
The uploads directory is chmodded 0700 on every start
HedgeDoc resets permissions on the uploads directory to 0700 each time the container starts. That is fine for a named volume, but if you bind mount uploads and serve them directly from nginx on the host, the web server gets permission denied after every restart. Set UPLOADS_MODE to something more permissive to stop it.
CMD_DOMAIN mismatches break the app in subtle ways
CMD_DOMAIN takes a bare hostname, one only, with no scheme and no path. Get it wrong and pages load but websockets fail, so editing appears to work locally and never syncs, or share links point at localhost. Set CMD_PROTOCOL_USESSL and CMD_URL_ADDPORT to match your proxy at the same time; these three together are the usual cause of a broken reverse proxy setup.
SQLite is offered and should not be used
The configuration accepts sqlite:///data/sqlite.db and the compose comments mark it NOT RECOMMENDED in capitals. Concurrent websocket writes against SQLite is exactly the workload it handles worst, and the failure shows up as lost edits under load rather than an error. Use PostgreSQL, and note the compose file also warns not to bump the Postgres major version without migrating.
Version 2 has no migration path yet
HedgeDoc 2 is a full rewrite that started in 2020, released alpha 1 in October 2023, and still has around 50 open issues on the 2.0 milestone as of September 2026. Data export and import were listed as incomplete in the alpha. Plan on staying on 1.x for the foreseeable future and keep your own Markdown exports, since a supported upgrade tool does not exist.
Specifications#
- Category
- Documents, notes and knowledge
- Licence
- AGPL-3.0 (Copyleft)
- Written in
- TypeScript / Node.js
- First release
- 2020
- Maturity
- Mature
- Datastore
- PostgreSQL (MariaDB/MySQL supported, SQLite discouraged)
- Default ports
3000- Ships as
- docker compose, node from source, community packages
- arm64 builds
- Yes
- Identity
- Native OIDC. Generic OAuth2/OIDC via the `CMD_OAUTH2_*` variables plus LDAP, SAML, GitHub, GitLab and Google; local email sign-in also exists and is on by default.
- Replaces
- HackMD, Google Docs (meeting notes), Etherpad, Notion (shared scratchpads)
- Project site
- hedgedoc.org
- Source
- github.com/hedgedoc/hedgedoc
- Documentation
- docs.hedgedoc.org
Alternatives to HedgeDoc#
Everything else in documents, notes and knowledge, closest in operational weight first.
| Tool | Ops load | Idle RAM | Licence |
|---|---|---|---|
| BookStack | 2, Light | 260 MB | MIT |
| Trilium Notes | 2, Light | 200 MB | AGPL-3.0 |
| Docmost | 3, Moderate | 500 MB | AGPL-3.0 core, proprietary Docmost Enterprise licence for `ee` directories |
| Paperless-ngx | 3, Moderate | 450 MB | GPL-3.0 |
| Wiki.js | 3, Moderate | 260 MB | AGPL-3.0 |
| Outline | 4, Heavy | 550 MB | BUSL-1.1 (Change Date 2030-09-01, converts to Apache-2.0) |
Where HedgeDoc comes up elsewhere#
Head to head
Migration guides
Sources#
Facts on this page were checked against the project's own material. Where a number is our own estimate rather than a published figure, the text says so.
Published . Last reviewed . Found something out of date? Tell us and we will fix it and log the change.