Askama: Jinja templates that compile into type-safe Rust
A template rendering engine based on Jinja, generating type-safe Rust code at compile time.
At a glance
- What is it?
- Askama is a template engine for Rust that reads Jinja-style templates and generates Rust code at compile time from a struct you define, so template errors surface in the compiler rather than at request time. The trade is that changing a template means rebuilding the crate, and the language it accepts is deliberately a subset.
- Who is it for?
- Askama fits Rust services that render HTML and want the template contract expressed in the type system, a shared vocabulary between front end and back end developers, and compile-time failure when a template references a field that no longer exists. It does not fit a product where non-engineers must edit templates in production, or a codebase that needs template logic with mutation, since Askama variables are immutable and the syntax set is bounded.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 3 days ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Your struct is the schema, not a bag of runtime values
Askama works in a way that is unusual among template engines. Instead of handing a template a map of values at runtime, you define a Rust struct, derive the Template trait on it, and the macro generates Rust code that renders the template file at compile time. The generated code is compiled into your crate.
The consequence is that the field names in the struct are the variable names available in the template, and the compiler is what checks that they line up. A template that refers to a field you deleted is a compile error rather than a blank spot on a web page. That is the whole argument for the design, and it is why the project describes the result as type-safe Rust code generated from your templates.
The same direction applies to the data. Variables carry no mutability in Askama, and both the template source and its output must be valid UTF-8. The engine works on stable Rust, and it also ships debugging features to assist in template development.
The interesting part is that nothing about the template is interpreted at runtime. Askama is a compiler, not a renderer with a template string, and that difference explains both its safety story and its costs.
Adding the crate and rendering hello.html
The dependency goes into Cargo.toml with a single command, and the workspace in the repository is versioned together with it.
cargo add askamaNext you create a directory called templates in your crate root and put a file named hello.html inside it, holding the template source.
Hello, {{ name }}!Then, in any Rust file in the crate, you bring the trait into scope, derive it, and point it at the template path relative to the templates directory.
use askama::Template; // bring trait in scope
#[derive(Template)] // this will generate the code...
#[template(path = "hello.html")] // using the template in this path, relative
// to the `templates` dir in the crate root
struct HelloTemplate<'a> { // the name of the struct can be anything
name: &'a str, // the field name should match the variable name
// in your template
}Rendering happens through the same struct, and the render call returns a Result, so a failure at that point is something you have to handle rather than ignore.
fn main() {
let hello = HelloTemplate { name: "world" }; // instantiate your struct
println!("{}", hello.render().unwrap()); // then render it.
}At that point the example compiles and runs. The struct name is yours to choose, but the field name has to match the variable name used in the template.
The Jinja subset Askama accepts, and where it stops
The syntax comes from Jinja, and the supported set is listed plainly. Templates support inheritance, loops, if/else statements and includes, and macros. There are some built-in filters and you can add your own. Whitespace can be suppressed with '-' markers, HTML escaping can be opted out of, and the syntax itself is customizable.
Two of those entries carry more weight than the rest for a server rendering HTML.
The first is the opt-out escaping. Escaping is on by default and you have to choose to turn it off, which is the safer direction for content you did not write yourself. The repository keeps escaping in its own crate, askama_escape, and ships a custom-escaper example, which tells you the mechanism is meant to be replaced when your output is not HTML, say a JSON API or a plain text format.
The second is syntax customization. Combined with own filters, it means the template language can be bent towards your conventions, but the documentation book, not the README, is where the details live. The README itself is a summary of capability, and the book at askama.rs is the reference.
Compile-time generation moves errors into the compiler
The advantage and the cost of Askama are the same mechanism seen from two sides.
On the advantage side, a template with a syntax error or an unknown variable fails your build rather than a request. In a deployment pipeline that is exactly the behaviour you want, and it is why the project can claim that template code is compiled into your crate for performance, since the rendering work becomes ordinary Rust the optimiser can see.
On the cost side, a template is part of your build. Change a template file and the crate has to be recompiled, which is a different feedback loop from the runtime engines people are used to. The project works around this with debugging features that assist in template development, and with an online playground where you can try the code generation without a local toolchain.
The workspace structure shows how much machinery sits behind the macro. askama holds the main crate, askama_derive the derive macro, askama_parser the template parser, askama_escape the escaping, and askama_macros the supporting macro layer. There are also testing crates for no-std, for a custom allocator and for a renamed dependency, which is the kind of setup that only matters if the crate is expected to be pulled into other projects with unusual constraints.
A fork, a merge, and a fork name you will still meet in blog posts
The project carries a piece of history that trips up newcomers. At one point Askama was forked into Rinja, and the two later merged back into Askama. The project explains this in a post linked from the README, and the practical consequence is that older blog posts, tutorials and dependency lines may refer to Rinja.
The current distribution channels are ordinary. The book is hosted with readthedocs at askama.rs, the API documentation is on docs.rs, the crate is on Crates.io, and the code lives on GitHub. Feedback goes to the issue tracker, and the project asks for bug reports, documentation requests and general feedback there.
The examples directory is a good map of where the engine lands in practice. There are sample applications for actix-web, axum, poem, rocket and warp, plus the custom escaper example, which is the clearest signal that Askama is aimed at web services rather than at build scripts or command line tools.
Where Askama is the wrong tool
The obvious mismatch is with a product whose templates change without a rebuild. A runtime engine reads a template at request time, so a designer can edit a file and see the result; the project's own history mentions Tera in the context of a switch. Askama cannot do that by design, because the template becomes part of the compiled crate.
The second mismatch is language expressiveness. Variables in Askama carry no mutability, and the supported constructs are a bounded list. If your templates need to build up state, manipulate data structures, or call arbitrary Rust helpers, you are fighting the language rather than using it. The escape hatch is to do the work in Rust and pass plain values in, which is a fine design, but it is a design, and it means the template stays simple.
The third case is output that is not HTML and is not text either. The default escaping assumes HTML, so anything you emit into another format needs the escaping mechanism replaced or disabled, and a mistake there is a security problem rather than a formatting bug. The custom escaper example exists for this reason.
None of these make Askama a poor default for a Rust web service. They do define the boundary: it is a compiler for a small, safe language, not a general expression engine.
Licence, toolchain floor and the release rhythm
The workspace metadata states the licence as MIT OR Apache-2.0, while the repository itself is listed under Apache-2.0. Both are permissive, and either can be chosen without copyleft obligations, which is the usual reason to check which one you are shipping under when you vendor the code.
The toolchain requirements are specific and modest. The workspace is on edition 2024 with rust-version 1.88, and the project states that it works on stable Rust. The workspace version is 0.16.1, matching the current release v0.16.1 published on 2026-09-04, which followed v0.16.0 on 2026-04-29 and v0.15.6 on 2026-03-24. The repository is not archived and the last push was on 2026-10-12.
The release spacing is a few months between minor versions, with patch releases in between. For a dependency that most projects take rather than modify, that is a comfortable rhythm, and the book and the changelog in the repository are where migration notes live.
The repository also carries a fuzzing directory, a deny.toml for dependency policy checks, and a book directory, which is a reasonable sign of the kind of work that goes on around the code rather than inside it.
Editorial conclusion
Askama fits Rust services that render HTML and want the template contract expressed in the type system, a shared vocabulary between front end and back end developers, and compile-time failure when a template references a field that no longer exists. It does not fit a product where non-engineers must edit templates in production, or a codebase that needs template logic with mutation, since Askama variables are immutable and the syntax set is bounded. Verify three things before you commit: the field names in your context struct against the variable names in the templates, the escaping behaviour for the content types you render beyond HTML, and the recompile cost in your build, because the template is compiled into the crate and every template edit triggers a rebuild.
Frequently asked questions
How do I add Askama to a Rust project?
Run cargo add askama, create a templates directory in your crate root, put your template file there, and derive the Template trait on a struct whose field names match the variables used in the template. The path attribute on the derive points at the file relative to the templates directory.
Does Askama escape HTML by default?
The feature list includes opt-out HTML escaping, so escaping is on unless you choose otherwise. For output that is not HTML, the project keeps escaping in a separate crate, askama_escape, and ships a custom-escaper example showing how to replace it.
What Rust version does Askama require?
The workspace metadata sets rust-version 1.88 on edition 2024, and the project states that Askama works on stable Rust. The crate is published on Crates.io under the name askama.
Can I use Askama with a Rust web framework?
The repository ships example applications for actix-web, axum, poem, rocket and warp, each under the examples directory. The engine itself does not depend on a framework, it renders a template into a string that you pass on.
What happens to my templates when I change them?
Askama generates Rust code from your templates at compile time and compiles it into your crate, so editing a template means rebuilding the crate. Errors in the template surface during compilation rather than when a request arrives, and the project offers an online playground plus debugging features to help with template development.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/askama-rs-askama)Was this useful?