···11+---
22+title: "Maudit is faster than most other static website generators, but"
33+description: "Your website changes less often than its content"
44+author: The Maudit Team
55+date: 2025-10-02
66+---
77+88+Objectively speaking, unless it does something weird, a binary using Maudit will generate a website pretty fast. This is expected: Maudit is pretty fast, Rust is pretty fast, native binaries are pretty fast, it checks out.
99+1010+## _However,_
1111+1212+If a Maudit project is a Rust project, and [Rust projects are slow to compile](https://www.reddit.com/r/rust/comments/xna9mb/why_are_rust_programs_slow_to_compile/) and you need to compile to build your website, doesn't that make Maudit slow by default?
1313+1414+Yes, **but**, there are a few things to consider:
1515+1616+- The slow completely cold compile and download are rare (much like you don't run `npm install` before every build)
1717+- Incremental warm builds are not that slow (< 3s~), and do not necessarily get slower as your website gets larger. The same blog with 5000 and 5 articles compile in the same amount of time (unless they're 5000 different pages and layouts, in which case, well)
1818+1919+And most importantly: **Not every change require recompilation.** Updating your Markdown content, updating frontend JavaScript or CSS, updating some images assets all don't require recompilation and are most definitely more common changes than changing your project's logic.
2020+2121+## Workarounds
2222+2323+You can also push this further, if your layouts do change often and you don't want to recompile your project on every change, use a runtime templating language like [minijinja](https://github.com/mitsuhiko/minijinja) or [Tera](https://keats.github.io/tera/docs/).
2424+2525+You can push it even further! [Routes paths are not static, they can be fully dynamic](https://maudit.org/docs/routing/#:~:text=The%20path%20can%20be%20any%20Rust%20expression) as such, you could load your routes fully at runtime.
2626+2727+> This example is available in the [examples/runtime-to-the-max](https://github.com/bruits/maudit/tree/main/examples/runtime-to-the-max) directory of the Maudit repository.
2828+2929+```rust
3030+use maudit::{BuildOptions, BuildOutput, content_sources, coronate, route::prelude::*};
3131+3232+#[route(format!("/dynamic/{}/", self.dynamic_page.0))]
3333+struct Dynamic {
3434+ dynamic_page: (String, String),
3535+}
3636+3737+impl Route for Dynamic {
3838+ fn render(&self, _: &mut PageContext) -> impl Into<RenderResult> {
3939+ self.dynamic_page.1.clone()
4040+ }
4141+}
4242+4343+fn main() -> Result<BuildOutput, Box<dyn std::error::Error>> {
4444+ let routes: Vec<Box<dyn FullRoute>> = std::fs::read_to_string("pages.txt")?
4545+ .lines()
4646+ .filter_map(|line| {
4747+ let mut parts = line.splitn(2, ": ");
4848+ match (parts.next(), parts.next()) {
4949+ (Some(name), Some(content)) => Some((name.to_string(), content.to_string())),
5050+ _ => None,
5151+ }
5252+ })
5353+ .map(|dynamic_page| Box::new(Dynamic { dynamic_page }) as Box<dyn FullRoute>)
5454+ .collect();
5555+5656+ coronate(
5757+ &routes.iter().map(|r| r.as_ref()).collect::<Vec<_>>(),
5858+ content_sources![],
5959+ BuildOptions::default(),
6060+ )
6161+}
6262+```
6363+6464+where `pages.txt` looks like this:
6565+6666+```txt
6767+hello: Hello!
6868+another_page: Another Page
6969+imnested/index: I'm nested!
7070+```
7171+7272+This is my CMS at home, don't judge me. More seriously, you could imagine loading pages from an actual CMS, a database, a `.json` file etc. And thus, combined with runtime templating, be able to add an infinite amount of pages without ever recompiling.
7373+7474+Maudit is a library, not a framework. Make it work for you!