Checked before it runs
quillo check holds the program to its types, list and map shapes, effects and error types, and warns about SQL built from values.
v0.5 · MIT · one binary, written in Rust
Routes, request patterns, pipelines and HTML are part of Quillo's syntax, so a web app reads like a list of what it answers. Components render on the server and resume in the browser, with no build step.
route GET /hello/:name = `Hello, ${name}!`route POST /orders { json: { type: "order" | "refund", qty: int } } { reply 201 { accepted: true, qty }}route GET /feed ? { page: int = 1 } = request | auth.required | load_feed(page) | render_feedThe cells behind this page are Conway's Life: a Quillo component running in your browser. Move your pointer across them.
? :, template strings and JSX-style HTML, without the surprises.Tour
:id(int) matches only digits.| pipes a request through middleware, and reply answers from anywhere.route GET /hello/:name = `Hello, ${name}!`route POST /orders { json: { type: "order" | "refund", qty: int } } { reply 201 { accepted: true, qty }}route GET /feed ? { page: int = 1 } = request | auth.required | load_feed(page) | render_feedDemo
This page is a Quillo program. The component below was rendered on the server, and your browser took it over. Add an item, or click one to tick it off.
component Todo() { ~items = [ { id: 1, text: "Read the tour", done: true }, { id: 2, text: "Write a route", done: false }, ] ~draft = "" let left = items | filter((i) => !i.done) | len <form.todo @submit={() => { if trim(draft) != "" { items = items + [{ id: len(items) + 1, text: draft, done: false }] draft = "" } }}> <input bind:value={draft} placeholder="Add something…"/> <ul>{for i in items => <li key={i.id} class={i.done && "done"} @click={() => { items = items | map((j) => j.id == i.id ? merge(j, { done: !j.done }) : j) }}>{i.text}</li> }</ul> <small>{left} left</small> </form>}Speed
math, stats and vec give Python's exact answers, worked on by every core. How many times faster than Python 3.9, on a million floats (log scale; hover for timings):
stats.stdev1037×Quillo 0.65 ms · Python 674 msstats.mean611×Quillo 0.35 ms · Python 214 msstats.describe449×Quillo 1.7 ms · Python 764 ms (by hand)stats.histogram210×Quillo 0.6 ms · Python 126 ms (a loop)stats.correlation176×Quillo 1.4 ms · Python 246 msstats.linear_regression140×Quillo 1.3 ms · Python 182 msstats.median34×Quillo 1.3 ms · Python 44 mssort10×Quillo 4.6 ms · Python 46 msAnd more
quillo check holds the program to its types, list and map shapes, effects and error types, and warns about SQL built from values.
Text is escaped, cross-site posts are refused, sessions are signed cookies and javascript: URLs are blocked.
Or PostgreSQL, with the same functions. Transactions nest, and migrations run in order, once.
stream and events send an answer as it is made, from a CSV export to a model's reply word by word.
t("cart.items", { count }) picks plural forms by the language's rules, on the server and in components.
Split a part of an app into its own server without changing its code; calls are signed with HMAC.
math, stats and vec give Python's answers, on every core, in the server and the browser.
quillo app runs the same program in a native window, with the platform's own web view.
Get started
$ git clone https://github.com/wisp-one/quillo.git && cd quillo$ cargo build --release$ ./target/release/quillo run examples/notes.qwe --watchThen open http://127.0.0.1:8080. quillo check app.qwe finds mistakes without running, quillo repl tries things out, and the VS Code extension (or quillo lsp in any editor) adds diagnostics, hover and completion.