Guide

Possible or not

The questions people ask before choosing a language, or once they are a week into a program, answered in a line each, with where the rest is. "No" here means the code does not do it today; the way around it follows.

The language

Can I...
use classes, interfaces, generics or enums?No. Records (type User = { ... }) are checked maps; "a" | "b" is the nearest enum; list<T> and map shapes are the generics. See Records
declare constants?No const: a let that nothing assigns. Values themselves never change
mutate a list or map in place?No: push, set, + give new ones, cheaply when nothing else holds the old one. See Standard library
throw and catch exceptions?No: failures are error values, ? passes them on, ?? replaces them. A runtime error ends the request with a 500. See Errors
write async/await, threads or locks?No need: waits suspend the request and the server goes on; parallel overlaps waits. Long computing holds its instance: put it in Rust or run more instances. See Concurrency
use namespaces or modules?A file sees its own names, the builtins and what it takes with use, and two files may define one name. private keeps a name to its file, mount and service are the boundaries, and there are no prefixes (auth.login()). See Files of a program
recurse deeply?Up to 10,000 calls; there is no tail-call optimisation
rely on integer overflow wrapping, or bitwise operators?No wrapping: overflow is an error. There are no & | ^ << >> or **: bit.and, bit.or, bit.xor, bit.not, bit.shl, bit.shr, and pow
have the checker prove a match covers every case?Not yet: a value no arm takes fails when it comes
format code automatically?Not yet: there is no formatter
use Unicode names?Yes: let café = 1

Pages and the browser

Can I...
send the page before its slow parts, as React's Suspense streams them?Yes: state x = defer(load()) streams that component when its data comes, in the same answer. See Server functions
render on the server and have it interactive in the browser?Yes, that is what a component is: rendered on the server, resumed in the browser without being drawn again. See Components
render a component only in the browser, or mount one from a script?No: components start from the server's HTML, or inside another component
use npm packages, TypeScript, a bundler?No: component code is Quillo, compiled to JavaScript by quillo; a library is a <script> reached with js(...). See JavaScript libraries
use React-style context, portals, refs, lifecycle hooks?No context or portals; @mount is the one hook (its returned function is the cleanup) and gives the element. See Composition
split the bundle by route or load a component lazily?No: a page's bundle has every component it can show; it loads when someone reaches for it
use setTimeout, debounce or throttle?No setTimeout: run_after(ms, f) for once, and every(ms, f) under a state flag for a debounce. See Components
use localStorage, the clipboard, window?Through the page: js("localStorage.getItem", k). Nothing is built in for them
use event modifiers like @click.prevent?No: e.preventDefault() in the handler
scope CSS to a component, or use Tailwind?Yes: style in a component is scoped, a file's style styles its components, --with and style_with run Tailwind and PostCSS, and style_with(f) and build run an engine of the program's own, fed by classes(). See HTML literals
paste plain HTML into a page?Mostly: comments, quotes of either kind, unquoted values and the doctype are taken; unclosed <p> and <li>, <style> and <script> braces need changing. See From HTML
translate the interface?Yes, with plural rules, on both sides. See Translations
run the app in a desktop window?Yes, with a build that has the app feature (the release downloads do not). See Desktop apps
compile components to WebAssembly?Not yet: they compile to JavaScript

Serving

Can I...
serve HTTPS or HTTP/2 from Quillo itself?No: HTTP/1.1 on plain TCP; a proxy in front (limer, Caddy, nginx) does TLS. See What a route cannot do
write middleware?Yes, as a pipeline stage that replys, or for many routes at once in a routes group (prefix, middleware, request pattern, nested; see Route groups); there is no global hook, and no custom 500 page
answer CORS preflights?Not by itself: declare route OPTIONS and set the headers with respond (with no such route, OPTIONS gets 204 and Allow, no CORS headers)
serve a folder of HTML and other files as they are?Yes: quillo serve site, or files("site", path) in a route, with index.html, clean URLs and 404.html. See Static files
open WebSockets of my own?No: live, events with listen, and channels are the ways to push. See Channels
receive or send binary data?Only as files: file(), uploads, image.*. There is no bytes value; bodies are text
stream a response?Yes: stream, events. See Streaming
limit how often a client calls?Not built in: count in a table of your own. See What a route cannot do
put a time limit on a route?No: only sockets time out
see the visitor's address behind a proxy?Name it with --trust-proxy, and request.ip is the visitor's. Otherwise read x-forwarded-for from request.headers yourself; Quillo never trusts it
run several programs on one port?Yes, in one process: mount or service /prefix. See Mounting programs
listen on a Unix socket, or run behind FastCGI?Yes: --listen unix:PATH, and quillo fcgi for mod_fcgid or nginx's fastcgi_pass. See Quillo on a shared server
run on shared hosting (cPanel)?Where the account has mod_fcgid, with quillo fcgi and plugins built beforehand; not through Passenger. See Quillo on a shared server
serve a site as static files?Yes, when its components call nothing on the server: fetch every page and the bundles it loads, and upload them
make requests run once when retried?Yes: idempotent. See Idempotent requests

Real time

Can I...
have pages follow the database without writing a socket?Yes: live(load), over one WebSocket a page. See Live data
see changes made by other programs (psql, a cron script, a trigger)?No: only writes made through Quillo, and publish. Have the other program call a route that publishes
push to one user?Yes: a topic of theirs (watch and publish), or channel.send to their page. See Channels
use UDP, WebTransport datagrams, live video?Yes: udp.*, channels, media.*. See UDP, Media
connect pages to each other (WebRTC)?No: everything goes through the server, which relays video as an SFU, with no TURN
record a stream?No: have the encoder write a copy
relay channels and streams across servers?No: live data is shared through limer (--register); channels and media are each server's

Data

Can I...
use SQLite, PostgreSQL, MySQL, MariaDB?Yes, with the same functions, several at once. See Database
use SQL Server, Oracle, Redis, MongoDB?Through a Rust crate in a .qwer file. See Other stores
use an ORM or a query builder?No: SQL with parameters, rows as maps, records to check their shape
stream a large result, or COPY, LISTEN/NOTIFY?No: page with limit; many-row inserts; publish for notifications
make a transaction over several databases?Yes: db.atomic, in two phases. Across services: no. See Several databases
give each customer a database?Yes: tenants. See Many tenants
encrypt SQLite at rest?No: the disk's encryption, or a server database
do exact money arithmetic?Yes: decimals and money. See Decimals
do data science?Python's math and statistics and numpy's array operations, on every core; no data frames or plotting. See Numbers and data
read CSV, XML, YAML, TOML?Not built in: the catalog's csv, xml, yaml and toml plugins, or split and re. No base64 yet. See Plugins
know the visitor's time zone on the server?Not by itself: the page tells it with a cookie. See Dates and times

Services and scale

Can I...
split an app into services without changing its code?Yes: service, in one process or --split. See Services
write a service in another language?Yes, if it answers Quillo's signed calls; the caller keeps a .qwe file of its signatures, or the service answers _contracts. See Services
deploy an app without its services' code?Yes: with an address and no file, the app asks the running service for its functions. See Services
authenticate services with keys of their own, OAuth 2.0 tokens, JWTs or mutual TLS?Yes: auth where a service is declared, accept_calls in it, for [...] on a server fn. See Authentication between services
call an API that speaks only HTTP/2, as Apple's push service (APNs) or gRPC?No: http.* speaks HTTP/1.1 only. Use another program for those calls, or an API that takes HTTP/1.1 (Firebase Cloud Messaging's v1 API does)
call out through a company's proxy, trust an internal CA, or present a client certificate?Yes: HTTPS_PROXY and NO_PROXY are read, and http.* takes ca, cert and key. See HTTP client
use every core?Yes: --instances N, each with its own variables. See Concurrency
run several servers?Yes, behind limer, sharing a database; live data follows. See Several servers
describe my API for a gateway?Yes: quillo docs, --describe. See The program's API (OpenAPI)
add a copy of a service while it runs?Yes: --join, or behind limer with --register. See Copies that join
deploy without dropping a request?With --reload for the program's files; a new binary is a stop and a start, so run two servers for no gap
keep state in memory across restarts?No: globals start afresh; keep it in the database

Extending and tooling

Can I...
write part of a program in Rust?Yes: .rs or .qwer files, any crate, called like functions. See Rust
call C libraries?Through a Rust -sys crate
embed Quillo in a Rust program?It is a library crate, but not published, and its API may change. quillo::embed::Program runs a program with no socket, handed each request, as the apps do (on Unix only for now)
debug with breakpoints?Yes, in VS Code or any DAP client, on macOS and Linux, server and browser alike. See Debugging
get editor support?Yes: quillo lsp, and the VS Code extension
run untrusted users' code?Yes, sandboxed: run_script. Never as .qwer. See Scripts from users
get structured logs and metrics?JSON request lines (--log json) and Prometheus metrics (--metrics); errors are text lines. See Logs and metrics
configure with a file?Only .env, and a policy that takes away; everything else is an option. See the options at the start of this guide
limit what a program may do from outside it?Yes, with a policy: plugins, effects, hosts, variables, limits. See The policy
sandbox a program with the system's help (seccomp, Landlock)?Not yet: a policy holds Quillo code, not a plugin's Rust
Thread
18Useful? Like it, or add to its thread below.

Thread 0 posts

On Possible or not: questions, tips, corrections, and code that uses it.

No posts yet. The first one opens the thread.

    Edit this page on GitHub · made from the user guide · questions on Discord or r/quillo