Docsman

June 13, 2025

Rust ·Svelte

When building small projects, I often skip writing documentation for them. I know it’s valuable (and you should do it), but it’s also inconvenient. You usually have three options:


  1. Use a tool like docusaurus or some other documentation generator.
  2. Use an external service like Clickup
  3. Use a bunch of markdown files in your repository

Now these options all have downsides. Using a tool like docusaurus is great, but it’s a bit overkill for a simple project as you have an entire new app in your repository (or an entirely new repository).

Using an external service is also not great, as you have an external source of truth for your documentation, and it doesn’t really play nice with version control (you can’t have different documentation pages for your different versions of your codebase). Also, it’s a bit overkill for a simple project.

Using a bunch of markdown files is usually what I default to as it aligns with my wishes to be able to put docs in my source control, but it is also not very user-friendly to view.


To fix all my issues with writing documentation, I decided to build a quick prototype for a documentation manager that I call Docsman. I wanted a few things:


  1. Standalone binary
  2. Simple UI
  3. Markdown support
  4. Hot-reloading


Svelte with Rust

I decided that I want to use Svelte as my frontend framework, but including this file inside of my binary proved to be a bit of a challenge. The default way of creating a Svelte application, using pnpm dlx sv create creates a Sveltekit app, which is slightly different from a regular Svelte app as it includes an entire routing system (which is nice when you need it).


To align with my goal if a single standalone binary, I needed to include the frontend inside of the binary itself. The problem however is that Svelte, by default, outputs multiple files (like styles and scripts). Luckily for me, I found the vite-plugin-singlefile package which allows me to bundle the frontend into a single file.

Then, I could use the include_str! macro to include this entire file as a string in my binary. The drawback of this is that the binary is bigger, but it’s also in memory so no disk I/O is required. It also doesn’t have any external dependencies.



Hot Reloading

To implement hot-reloading I had a couple of options for notifying the frontend of changes:


  1. Polling the server for changes
  2. Server-sent events
  3. WebSockets

I decided to use websockets, as I was most familiar with them.

Then, to actually detect the changes in the files, I used the notify crate.



Conclusion

Docsman is a lightweight, standalone documentation manager that meets my needs for simple projects. It offers a simple UI, markdown support, and hot-reloading, all within a single binary. While still a prototype, it has proven useful for personal projects.

For those interested, the source code is available on GitHub. Contributions and feedback are welcome!

Copyright © 2016-2025 boris.foo (formerly borisnl.nl), All rights reserved.