Skip to content

Releases: docs-plus/docs.plus

v2.0.1

Choose a tag to compare

@HMarzban HMarzban released this 31 Aug 07:59

🧹 A housekeeping release

Nothing changes for you as a writer or a reader. No new buttons, no moved menus. 🙂

We spent this round looking under the floorboards — at what actually runs when you open a pad. Turns out we were carrying a lot of things we never use.

Every number here comes from the real production server, not somebody's laptop.


🪶 Our images went on a diet

before after
🌐 webapp 727 MB 332 MB −54%
⚙️ backend 5.67 GB 961 MB −83%

Two things were hiding in there.

The webapp was shipping a C++ compiler, python3 and a second JavaScript runtime. It never used any of them. 😅

The backend was even better: it carried two entire copies of Next.js and four native build binaries. For a service that does not render a single page.


⚡ Everything got faster

before after
🐳 Production build 997s 683s
🧪 Backend tests 7.9s 3.1s
🧩 Extension tests 209s 88s
✅ Full local check 290s 163s

That last one matters most day to day. Waiting five minutes before every push is very different from waiting under three. ⏱️


🐛 Four bugs we found by accident

We were not hunting for these. They turned up while measuring other things.

🔴 A crashed backend was reporting success. It exited with a "everything is fine" code, so nothing downstream ever noticed. It now exits properly and gets restarted.

🎯 Our test splitter was never reading its own timings file. It was dividing work by counting files instead of by how long they take. One worker sat idle while another ran three times as long.

A test was waiting exactly two seconds, then checking if a process had stopped. If shutdown took longer, a perfectly healthy process failed the test. It now just waits for the actual event.

🔑 Our secret-file filter only looked in one folder. A key file in a subfolder could still slip into a build. Fixed.


🏃 Under the hood

We are now on Bun 1.4.0 everywhere. Our servers were already running it — the code just had not caught up and said so.


🤯 The one that surprised us

One single line of configuration — a permissions command — was costing 125 seconds of every production build and quietly storing an extra 1.91 GB in the image.

On a Mac laptop, that same line takes 1.8 seconds.

So it looked like 0.7% of the build. Completely ignorable. On the real server it was the single biggest thing in this entire release. 🤦

The lesson we are keeping: when your laptop and your production logs disagree, believe production.


📖 Full detail in the CHANGELOG.

Thanks for reading, and thanks to everyone poking at docs.plus and telling us what breaks. 💚

docs.plus 2.0.0

Choose a tag to compare

@HMarzban HMarzban released this 26 Aug 08:51

docs.plus — Get everyone on the same page. Free, open-source collaborative documents for communities. A contents list where every section carries its own chat count, and seven people are in the document right now.

docs.plus is a free, open source tool for real-time collaborative documents. Every heading in a document has its own chatroom, so a discussion stays next to the section it is about. It is built on Next.js, Tiptap, ProseMirror, Yjs and Hocuspocus, and you can run it on your own server.

Here is the part we like. The version string stopped moving on 2023-08-03, at 2.0.0-beta.103. The
work did not. For three years docs.plus shipped chat bound to headings, version history, media, document
conversion, themes and an entire backend, all under a number that said beta and meant nothing.

Today the number catches up. 2.0.0 is the first stable product tag after the Etherpad years, and
everything below is what those three quiet years actually built. @docs.plus/webapp and
@docs.plus/hocuspocus both carry 2.0.0. The admin dashboard stays 1.0.0. The five
@docs.plus/extension-* packages shipped 2.0.0 to npm on 2026-08-11, and this tag does not change them.

A docs.plus document. The table of contents sits on the left, the pad in the middle, and a Heading Chatroom docked on the right.

📄 What docs.plus is

Open a document, type a Title, then add a heading. The table of contents (TOC) builds itself while you type. Every TOC row carries a chat button. Press it and the Heading Chatroom for that section opens.

A document is a tree of headings, and that shape drives the whole product. A heading is a TOC row, a fold target, a link you can send, and a Heading Chatroom. The server stores that tree in a flat heading schema, so one id serves the TOC, the Heading Chatroom and the URL.

Stack. Next.js 15, React 19, Tiptap 3 and Tailwind CSS 4 in the pad. Hono, Hocuspocus, BullMQ and Prisma on the server. PostgreSQL and Redis behind them. Supabase for accounts, chat and storage. Bun is the only package manager. The docs.plus code is MIT, and the projects it builds on carry their own licences.

🚀 Try it in five minutes

  1. Type new.docs.plus in the address bar. You land in a fresh document. There is no sign-up.
  2. Write a Title, press Enter, and add a heading.
  3. Press the chat button on that heading, or on its TOC row. Its Heading Chatroom opens.
  4. Sign in, press Join Channel, and type your first message.
  5. On a desktop, drag one TOC row and the whole section moves with it.

You can read this document's Heading Chatroom without an account. Sending a message, restoring a version, attaching a file and exporting the document all need you to sign in.

✨ Highlights

  • Heading Chatroom. Every heading carries one. Open it from the heading, or from its TOC row. Unread counts land on TOC rows and heading chips, once you sign in.
  • The TOC does more than list headings. It rebuilds while people type. Fold a section and the pad collapses it to paper strips, stored in your own browser. On desktop, drag a row to move the whole section, or sideways to change its heading level.
  • Reply in Thread. Turn a chat message into a new heading in the document. It lands one level below the current section, and its Heading Chatroom opens.
  • Document Version History. List saved versions and open one without editing it. Compare two saved versions and docs.plus reports which whole blocks differ. Restoring a version needs you to sign in. Share a #history?version= link.
  • Document conversion. Import Word or Markdown. docs.plus shows the lossy-conversion warnings before you press Replace document. Export Word (docx), Markdown (md) or OpenDocument (odt). Import and export both need you to sign in. Print a PDF from the browser print dialog.
  • Chat media. Sign in, then attach up to 10 files, each 10 MB or smaller. The Feed album tiles pictures and video inside the message. Open the Gallery playlist to step through them.

How it works

A chatroom on every heading. A message in the chat can become a new heading in the document.

The table of contents. Every heading is a row, the row lights up as you scroll, and folding a row creases the page into strips.

What the version history holds: saved versions grouped by day and by writing session.

⚠️ Breaking changes

  • The Etherpad pad is replaced by the Next.js pad. Etherpad plugins do not load.
  • Private is owner-only. A signed-in stranger is denied. An anonymous visitor must sign in.
  • An Open document refuses Access mutation. The two locks move only when an owner exists.
  • Turning Private or Read-only on no longer claims ownership.
  • On an owned document, only the owner may change title, description and keywords.
  • Turn Private on and the control clears and disables Read-only, until the document is public again.
  • Anonymous sign-in is off. Local development now behaves the same way as production.

If you self-host or call the API, the backend carries fifteen more breaking rows. Content is addressed by documentId only, never by slug. Content and version routes need the Supabase service-role key. A heading-less replace is refused with 422. A soft-deleted document refuses new WebSocket joins. Read them all in Backend changes in 2.0.0.

🧭 Migration

If you used Etherpad docs.plus. Open your documents at docs.plus. The editor is the Next.js pad. Etherpad plugins do not load.

If you treated Private as any signed-in user. Private now means only the owner may open the document. Sign in as the owner to change the locks. An Open document has no owner, so it cannot turn Private.

If you claimed an Open document by turning Private on first. That path is gone. The server records a signed-in creator as the owner. A later lock change never sets one.

If you self-host. Run the one-shot migration job first, and let it finish before any process starts.

docker compose -f docker-compose.prod.yml --env-file .env.production run --rm migrate

Then start the worker, then collaboration, then REST. If your documents carry nested heading history, run migrate:nested-to-flat from apps/hocuspocus.server first. If they carry legacy PascalCase media rows, run migrate:media-node-names. Snapshot PostgreSQL before either.

If you consume the npm extensions. They already shipped, and npm latest does not change today. Read each package CHANGELOG.md.

🆕 Added, by area

Area What is there
The pad Title locked as the first line · Block style from Normal text to Heading 6, with a one-frame stepper on mobile · bold, italic, underline, strikethrough, highlight · bullet, ordered and task lists · a code block that highlights the nine languages it detects · Tab indent · Clear Formatting · Markdown paste · a breadcrumb of parent headings inside an empty block · a mobile pad that opens in read mode, with a pencil button to start typing
The TOC A tree that rebuilds while you type · a read marker that follows the pad · fold a section into paper strips, stored in your own browser · Filter with typeahead, chips, Reset and Match all · filter terms in the URL, so a filtered view is a link · drag to move a section, and drag sideways to change its level, on desktop
Heading Chatroom Chat per heading · mentions and @everyone · a saved chat draft per heading, in that browser · sign in to reply, edit or delete your own messages, add a reaction, save a Bookmark, or record a voice note up to five minutes
Version History Versions grouped by day and by writing session · compare two · sign in to restore one · #history?version= links · versions older than 30 days thinned to one per day, and a name you typed kept ...
Read more

v2.0.0-alpha.103

v2.0.0-alpha.103 Pre-release
Pre-release

Choose a tag to compare

@HMarzban HMarzban released this 12 May 08:52

🎉 Welcome to the rebirth of Docs.plus! After a transformative journey that began with Etherpad, we've arrived at a new release that we're absolutely thrilled to share with you.

Docs.plus has been rebuilt from the ground up. 🚧 Our path led us to ProseMirror 📝 and Tiptap ✏️, and we chose Vite.js ⚡ and Hocuspocus 🎩 to serve as our foundation.

🎢 Along the way, we faced a fair share of ups and downs. We started questioning whether we were overcomplicating things in trying to meet our goals. So, we took a step back and decided to refactor the client side. We've now transitioned from React (Vite.js) to Next.js. 🔄 You can read more about this decision and the reasoning behind it here.

🚀 We can't wait for you to experience the new Docs.plus. This is just the beginning, and we have many enhancements and improvements 🆙 lined up for the next steps. There's much work ahead of us, but we're committed to making Docs.plus better with every release.

🎉 Meet Our New Contributor

A big shoutout to our new contributor:

@shayanmemarzade 🙌 made their first contribution in Pull Request #86. We're thrilled to have you onboard!
Full Changelog: Explore the complete set of changes in this release here.

🙏 Thanks for being a part of the Docs.plus community. Your support and feedback inspire us to keep pushing the boundaries of what our tool can do.

v1.8.18

v1.8.12

Choose a tag to compare

@HMarzban HMarzban released this 09 Apr 05:26
Merge branch 'master' of https://github.com/nwspk/docs.plus