Why?

The previous version of the site ran on Hugo — an excellent static site generator. But over time, a few problems accumulated:

  1. PHP dependency for OAuth and contacts. Hugo generates static HTML, while dynamic features (Google/Yandex login, displaying contacts after login) required a separate PHP backend. Two runtimes — double the complexity.

  2. Manual rebuild on every change. Write an article — rebuild and redeploy the entire site. This discourages writing.

  3. Code duplication. PHP shortcode processing and Hugo templates lived in separate worlds but essentially did the same thing.

I wanted something more cohesive. One binary containing everything: the blog, authentication, and static file serving.

Why Rust?

I've been writing Rust in my free time and enjoy its approach: zero-cost abstractions, memory safety without a garbage collector, and an excellent web ecosystem (Axum, Tera, pulldown-cmark).

A Rust server starts in milliseconds, uses minimal memory, and keeps all content in memory — no external services. The only local database (SQLite) is used for the page view counter, sessions, and login audit.

Architecture

One binary (~18 MB) + directories = the whole site:

  • content/ — Markdown files with TOML frontmatter
  • base/themes/{theme}/ — Tera templates, SCSS and i18n of the active theme
  • base/static/ — user overlay for static assets
  • config.toml — configuration
  • .env — OAuth keys

Themes are mandatory and switched via theme in config. The code follows MVC layers: model/, view/, controller/, service/, router//middleware/, server/.

No PHP. No rebuilds. Edit a .md file — the site updates instantly via hot reload.

For a detailed description of the features, architecture and tech stack, see the Blog server project page.

Result

The site is fast, compiles cleanly, has no external runtime dependencies, and is easy to deploy. Writing articles became simpler: save a Markdown file — and changes are live instantly.

The project has grown past a pet project: a rich test suite, ≥75% line coverage, zero clippy warnings — and every commit passes the whole check suite.

The binary cross-compiles for glibc 2.17 via cargo zigbuild — works on CentOS 7+ and any modern Linux. Deployment is a single build.zip (~18 MB), a Docker image, or a systemd unit.

It was a useful engineering exercise. The project remains interesting and keeps evolving.