In the Rust web framework world, Axum and Salvo are often put side by side. Both are written in Rust, both run on top of hyper, and both are async. But once you’ve built a few real services with each, you’ll realize they aren’t really competing on the same axis at all — they represent two genuinely different worldviews. This article isn’t about putting one above the other (Axum is an excellent framework); it’s about showing how a different abstraction layer leads to a noticeably different developer experience and expressive power.
The Axum version referenced here is 0.8.x. One quick clarification: Axum 0.8 followed matchit 0.8 in switching its path-parameter syntax from :name / *name to {name} / {*name}, which on the surface looks almost identical to Salvo’s. But the real difference has never been “braces vs. colons” — it’s the abstraction model itself.