---#[model]structTodo {
#[validate(len = 1..=100)]
text: String,
}
staticTODOS: Table<Todo> = Table::saved();
#[action]fnadd(todo: Todo) {
TODOS.add(todo)?;
}
#[action]fnremove(id: u64) {
TODOS.remove(id)?;
}
---
<title>Todos (${TODOS.len()})</title>
<metaname="description"content="A todo list that saves its rows and checks what you add.">
<h1>Todos</h1>
<formaction="?/add"fields />
{#eachTODOS.all() astodo}
<p> ${todo.text}
<buttonaction="?/remove&id=${todo.id}">
Remove
</button>
</p>
{/each}
localhost:3000
Todos (3)
Buy milk
Write the docs
Learn to code
A Page Is One File
Put the model, the form actions and the markup of a page in one file. Wisp compiles the file to Rust, so the compiler checks your template as it checks the rest of your code.
Benchmarks
Each framework runs on the same machine with a release build. The charts show every contender, also the tests where Wisp loses.
TechEmpower plaintext and JSON tests. Not an official TechEmpower result.
Plaintext, pipelinedreq/s, 16 requests per write, best of 256 to 16,384 connections
Wisp
8,140,071
Actix Web
3,584,014
Axum
2,390,269
Hono (Bun)
603,962
Fastify
414,802
Express
278,367
Hono (Node.js)
217,621
Nuxt
165,092
SvelteKit
104,899
Next.js
15,129
JSONreq/s, one request per write, best of 16 to 512 connections