🪝 QAIL — The Universal Query Transpiler
Safe but Free. Write queries once. Run them everywhere. Zero lock-in.
Why QAIL?
For years, developers have been trapped between two choices:
- Raw SQL — Maximum freedom, but dangerous strings scattered across your codebase.
- ORMs / Query Builders — Maximum safety, but a "prison" of boilerplate and language lock-in.
QAIL is the third way.
We moved validation from the networking layer to the grammar level. By treating queries as a compiled language instead of raw strings, QAIL provides compile-time safety with the freedom of raw SQL.
- ✅ No language lock-in — Same syntax in Rust, Node.js, Go, Python, PHP
- ✅ No heavy dependencies — Pure logic, zero networking code
- ✅ No "big bang" migration — Adopt incrementally, one query at a time
- ✅ Works with your existing driver — SQLx, pg, PDO, psycopg2, etc.
-- SQL (The Assembly)
SELECT id, email FROM users WHERE active = true LIMIT 10;
# QAIL (The Source Code)
One line. Zero ceremony. Runs everywhere.
🚀 Installation
Rust (Native)
[]
= "0.6.1"
Node.js / Browser (WASM)
💡 Usage
Rust
use *;
// Parse and transpile
let sql = parse?.to_sql;
// Returns: "SELECT id, email FROM users WHERE active = true"
// Use with your existing driver (sqlx, diesel, etc.)
let users =
.fetch_all
.await?;
JavaScript / TypeScript
import from 'qail-wasm';
const sql = ;
// Returns: "SELECT id, email FROM users WHERE active = true"
// Use with your existing driver (pg, mysql2, etc.)
const result = await client.;
📖 Quick Reference
| Symbol | Name | Function | Example |
|---|---|---|---|
:: |
The Gate | Action (get/set/del/add) | get:: |
: |
The Link | Connect table to columns | users:'id |
' |
The Label | Mark a column | 'email'name |
'_ |
The Wildcard | All columns | users:'_ |
[ ] |
The Cage | Constraints block | [ 'active == true ] |
== |
The Equal | Equality check | 'status == "active" |
~ |
The Fuse | Fuzzy match (ILIKE) | 'name ~ "john" |
| |
The Split | Logical OR | 'a == 1 | 'b == 2 |
& |
The Bind | Logical AND | 'a == 1 & 'b == 2 |
+/- |
Sort Order | ASC/DESC | -created_at |
N..M |
The Range | Pagination | 0..10 |
$ |
The Var | Parameter placeholder | $1 |
! |
The Unique | DISTINCT | get!:: |
<- |
Left Join | LEFT JOIN | users<-profiles |
-> |
Inner Join | INNER JOIN | users->orders |
📚 Examples
Basic SELECT
All Columns
Sorting & Pagination
Fuzzy Search
UPDATE
DELETE
JOINs
# → SELECT name, avatar FROM users LEFT JOIN profiles ON ...
📦 Schema Management (Migrations)
Create and modify tables with the same concise syntax.
Create Table (make::)
)
# → CREATE TABLE users (id UUID PRIMARY KEY, email VARCHAR(255) UNIQUE);
# → COMMENT ON COLUMN users.email IS 'User email'
Constraints & Defaults
)
Composite Constraints
)
# → CREATE TABLE bookings (..., UNIQUE (user_id, slot_id))
Create Index (index::)
🌐 One Syntax. Every Stack.
QAIL provides multiple integration paths:
| Platform | Package | Description |
|---|---|---|
| Rust | qail-core |
Native crate, zero overhead |
| Node.js / Browser | qail-wasm |
WebAssembly module (~50KB) |
| C / C++ | libqail |
Universal C-API for FFI |
| Python, Go, PHP, Java | via C-API | Use libqail through your language's FFI |
The C-API Advantage
Instead of building separate bindings for each language, we expose a Universal C-API (libqail). Any language with FFI support can call QAIL directly:
// C / C++
const char* sql = ;
# Python (via ctypes or cffi)
=
=
// Go (via cgo)
// #include <qail.h>
import "C"
sql := C.GoString(C.qail_transpile(C.CString("get::users:'_")))
Same syntax. Same validation. Any driver.
🤝 Contributing
We welcome contributions!
📄 License
MIT © 2025 QAIL Contributors