Get started / Quidra 0.3.0

Install Quidra and run a program

Quidra ships as a native compiler with a REPL. Programs are compiled ahead of time through LLVM and Clang; the distribution intentionally does not bundle that backend toolchain, so install Clang 15 or newer alongside it.

01 / install

Download a release

Every release publishes archives for Linux, macOS and Windows on GitHub. Pick the one for your platform, then put the quidra executable on your PATH.

  • Clang 15+ for quidra FILE.qui, quidra run and quidra build (native code generation).
  • LLVM 15+ with lli for the REPL's ORC JIT.

Quidra 0.3.0 was released on 2026-09-27. Release notes and checksums are on the release page.

Debian and Ubuntu
sudo apt-get install ./quidra-linux-amd64.deb
quidra --version
Build from source instead

Requires CMake 3.20+, a C++20 compiler, LLVM and Clang 15+, and the libcurl, libpng, libjpeg, libtiff, libwebp and FFmpeg development packages. See the build section of the README for Windows.

Linux and macOS
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --parallel
ctest --test-dir build --output-on-failure
./build/quidra run examples/hello.qui

02 / first program

Write, run, build

Source files end in .qui. Top-level statements are the entry point, blocks are four-space indented, and there is no main to declare.

quidra hello.qui compiles to a hidden native artifact beside the file, runs it and removes it. quidra build keeps the executable.

hello.qui
print("Hello from Quidra")
output
Hello from Quidra
Run directly
quidra hello.qui
Build a persistent executable
quidra build hello.qui -o hello
./hello

03 / REPL

Evaluate interactively

Run quidra with no arguments in a terminal. Each submission is parsed, checked, lowered to LLVM IR and executed natively through ORC JIT; declarations stay available for later submissions, and a rejected submission leaves the session intact.

:type expression prints a static type, :reset clears the session, :help lists the rest.

terminal
$ quidra
Quidra 0.3.0
>>> int x = 5
>>> x * 8
40
>>> int square(int value)
...     return value * value
...
>>> square(6)
36

04 / tooling

Let the compiler explain itself

The same frontend that compiles your program answers questions about it. Diagnostics have stable codes and exact spans, formatting is canonical, and the typed IR and generated LLVM IR are one command away.

A failed check is data, not prose. Here is the JSON for an uninitialized read:

Compiler commands
quidra check program.qui --json    # diagnostics with codes and exact spans
quidra fmt program.qui --check      # verify canonical formatting
quidra ir program.qui               # typed Quidra IR
quidra llvm program.qui             # generated LLVM IR
quidra inspect program.qui          # typed source nodes with ids and hashes
quidra lsp                          # Language Server Protocol over stdio
uninitialized.qui
int x
print(x)
quidra check uninitialized.qui --json
{"ok":false,"truncated":false,"diagnostics":[{"code":"UNINITIALIZED","message":"Binding 'x' may be uninitialized.","file":"uninitialized.qui","span":{"start":{"line":2,"column":7},"end":{"line":2,"column":8}}}]}

05 / packages

Install first-party packages

Packages are source packages installed from immutable release tags, never from a moving branch. Official distributions use the quidra- prefix; the import name stays short.

Each package release declares the compiler range it supports in quidra.package; with no version written, the newest release compatible with your compiler is chosen, and an incompatible request fails instead of silently picking another version. Vision 0.3.0 and DNN 0.3.0 support Quidra 0.3.0. See package management for the full contract.

Package manager
quidra install quidra-vision   # newest release compatible with this compiler
quidra install quidra-dnn
quidra list
quidra lock program.qui         # pin versions and SHA-256 in quidra.lock
In source
import vision
import dnn

06 / in the browser

Or start in the browser

The Quidra Playground runs the real compiler frontend, compiled to WebAssembly, in your tab: check, format, lower to typed IR, inspect and patch, with nothing uploaded anywhere. It deliberately has no Run button; execution needs the native toolchain above.

Open the Playground
basics.qui
int count = 3
auto name = "Quidra"
print("Hello, {name}")

int[] original = [1, 2, 3]
int[] copy = original
copy[0] = 9
print("original[0] = {original[0]}, copy[0] = {copy[0]}")

int total = 0
for value in original
    total += value
print("total = {total}")

for i in range(0, count)
    if i == 0
        print("first")
    elif i < count - 1
        print("middle")
    else
        print("last")
output
Hello, Quidra
original[0] = 1, copy[0] = 9
total = 6
first
middle
last