kvist-lang/kvist

A native, statically typed Lisp with a REPL that compiles to Odin.

48

stars

0

commits

Odin

primary language

Sep 9, 2026

updated

clojure
compiler
functional-programming
lisp
live-coding
macros
manual-memory-management
metaprogramming
native-code
odin
ownership
programming-language
repl
s-expression
systems-programming
transpiler

README

Kvist logo

Kvist

A practical Lisp for systems programming that compiles to Odin.

Kvist combines Clojure-inspired syntax, source macros, immutable data, and interactive development with a native, statically typed execution model. Ordinary values have Odin-like representation and ownership: allocation, mutation, and cleanup remain explicit, and generated programs require no VM or garbage collector.

Kvist transpiles to readable Odin, imports Odin core and vendor packages directly, and allows Kvist and Odin source files to live in the same package.

When data-oriented programming is a better fit, Data provides EDN in memory: immutable maps, vectors, sets, lists, keywords, symbols, and tagged values. This makes Hiccup, transactions, Datalog queries, configuration, and other data DSLs feel like Lisp without making every runtime value dynamic.

Highlights

  • Native REPL — submissions are checked and executed as native Kvist code, while definitions, values, imports, macros, and recent results persist.
  • Native by default — concrete structs, arrays, maps, pointers, procedures, allocators, and explicit ownership.
  • Data-oriented programming — immutable EDN-shaped values with destructuring, structural matching, persistent updates, typed validation, and decoding.
  • Fused transforms and iterators — expressive collection pipelines lower to direct loops without lazy sequences or intermediate collections.
  • Source macros — Lisp forms are transformed at compile time without adding a dynamic runtime object model.
  • Direct Odin interoperability — use Odin packages and types without a wrapper ecosystem, including core and maintained vendor packages.

Native Code And Data As Data

Ordinary Kvist values stay concrete and statically typed. This transform over native structs lowers to one direct loop:

(defstruct User {
  name: string
  active?: bool
})

(defn active-names [users: []User] -> [dynamic]string
  (into [dynamic]string
    (comp
      (filter .active?)
      (map .name))
    users))

When the shape itself is data, the same language can express Lisp-shaped DSLs as immutable values:

(defn page [title: string] -> Data
  [:main {:class "page"}
   [:h1 title]
   [:p "Ready"]])

(def names-query
  '[:find ?name
    :where [?e :contact/name ?name]])

The official HTML package renders the first value as Hiccup-shaped HTML. VevDB uses the same Data model for Datomic-style transactions, Datalog queries, rules, pull patterns, and query results.

Quickstart

Install the Odin compiler, clone this repository, and build the Kvist CLI from the repo root:

git clone https://github.com/kvist-lang/kvist.git
cd kvist
odin build src/cli/kvist

Add a main function to a hello.kvist file:

(defn main []
  (println "hello from kvist"))

Run it:

$ ./kvist run hello.kvist
hello from kvist

Or use the same file as context for the native REPL:

$ ./kvist repl hello.kvist
Kvist native REPL
kvist=> (+ 1 1)
2
kvist=> (defn square [x: int] -> int (* x x))
kvist=> (square 11)
121

To install the compiler and shipped packages under a separate root:

./scripts/install.sh ~/.local/lib/kvist
export PATH="$HOME/.local/lib/kvist/bin:$PATH"

Interactive Development

A REPL submission is ordinary Kvist: it is read, macro-expanded, type checked, ownership checked, lowered to Odin, compiled, loaded, and executed as native code. Definitions and supported typed values persist across submissions, and compatible redefinitions update later calls without replaying earlier forms.

The terminal client and editor-neutral JSONL protocol use the same native session. The Emacs client adds source-buffer evaluation, completion, documentation, retained value inspection, source-level stepping, execution traces, conditions and restarts, and attachment to running applications.

See the native REPL guide and Emacs guide.

Odin Interoperability

Kvist imports Odin packages directly:

(import os "core:os")
(import sha2 "core:crypto/sha2")
(import raylib "vendor:raylib")

Procedures, types, constants, enums, multiple return values, allocators, and errors retain their Odin semantics. Kvist and Odin source may also live in the same package and call each other without a wrapper layer.

See the Odin interoperability guide and interop examples.

More Language Features

  • Clojure-style threading, nested destructuring, and structural Data matching.
  • Typed Data validation and decoding into native structs, enums, and arrays, with precise error paths.
  • Explicit conditions and compiled restarts for programmatic or interactive recovery.
  • Parametric polymorphism, overload sets, multiple return values, pointers, custom allocators, and struct-of-arrays storage.
  • Inferred ownership boundaries, source-mapped diagnostics, compilation caches, and lifetime inspection.
  • Shipped packages for native collections, EDN, regular expressions, parallel work, testing, bit operations, strings, and immutable Data.

Tooling

./kvist check examples/language/hello.kvist
./kvist run examples/language/hello.kvist
./kvist repl examples/language/hello.kvist
./kvist test examples/coverage/packages/test-package-tests.kvist
./kvist eval examples/collections/higher-order.kvist '(threaded-total)'
./kvist expand examples/collections/higher-order.kvist '(threaded-total)'
./kvist lifetimes examples/collections/ownership-warnings.kvist

Run ./scripts/smoke.sh for a quick local check.

Platform Support

Kvist is tested on macOS and Linux. The core CLI and representative programs are also tested on Windows, but the complete test suite and shell-based tooling are not yet covered there.

Building Kvist requires an Odin toolchain supported by the host platform. The scripts in scripts/ require a POSIX-compatible shell.

Documentation

License

Kvist is licensed under the MIT License. See LICENSE.

Programs written in Kvist, and Odin code generated from user-authored Kvist source, are not required to use the MIT License merely because they were compiled with Kvist. Code copied from Kvist packages or runtime support remains under its applicable license.

kvist-lang/kvist

A native, statically typed Lisp with a REPL that compiles to Odin.

48

stars

0

commits

Odin

primary language

Sep 9, 2026

updated

clojure
compiler
functional-programming
lisp
live-coding
macros
manual-memory-management
metaprogramming
native-code
odin
ownership
programming-language
repl
s-expression
systems-programming
transpiler

README

Kvist logo

Kvist

A practical Lisp for systems programming that compiles to Odin.

Kvist combines Clojure-inspired syntax, source macros, immutable data, and interactive development with a native, statically typed execution model. Ordinary values have Odin-like representation and ownership: allocation, mutation, and cleanup remain explicit, and generated programs require no VM or garbage collector.

Kvist transpiles to readable Odin, imports Odin core and vendor packages directly, and allows Kvist and Odin source files to live in the same package.

When data-oriented programming is a better fit, Data provides EDN in memory: immutable maps, vectors, sets, lists, keywords, symbols, and tagged values. This makes Hiccup, transactions, Datalog queries, configuration, and other data DSLs feel like Lisp without making every runtime value dynamic.

Highlights

  • Native REPL — submissions are checked and executed as native Kvist code, while definitions, values, imports, macros, and recent results persist.
  • Native by default — concrete structs, arrays, maps, pointers, procedures, allocators, and explicit ownership.
  • Data-oriented programming — immutable EDN-shaped values with destructuring, structural matching, persistent updates, typed validation, and decoding.
  • Fused transforms and iterators — expressive collection pipelines lower to direct loops without lazy sequences or intermediate collections.
  • Source macros — Lisp forms are transformed at compile time without adding a dynamic runtime object model.
  • Direct Odin interoperability — use Odin packages and types without a wrapper ecosystem, including core and maintained vendor packages.

Native Code And Data As Data

Ordinary Kvist values stay concrete and statically typed. This transform over native structs lowers to one direct loop:

(defstruct User {
  name: string
  active?: bool
})

(defn active-names [users: []User] -> [dynamic]string
  (into [dynamic]string
    (comp
      (filter .active?)
      (map .name))
    users))

When the shape itself is data, the same language can express Lisp-shaped DSLs as immutable values:

(defn page [title: string] -> Data
  [:main {:class "page"}
   [:h1 title]
   [:p "Ready"]])

(def names-query
  '[:find ?name
    :where [?e :contact/name ?name]])

The official HTML package renders the first value as Hiccup-shaped HTML. VevDB uses the same Data model for Datomic-style transactions, Datalog queries, rules, pull patterns, and query results.

Quickstart

Install the Odin compiler, clone this repository, and build the Kvist CLI from the repo root:

git clone https://github.com/kvist-lang/kvist.git
cd kvist
odin build src/cli/kvist

Add a main function to a hello.kvist file:

(defn main []
  (println "hello from kvist"))

Run it:

$ ./kvist run hello.kvist
hello from kvist

Or use the same file as context for the native REPL:

$ ./kvist repl hello.kvist
Kvist native REPL
kvist=> (+ 1 1)
2
kvist=> (defn square [x: int] -> int (* x x))
kvist=> (square 11)
121

To install the compiler and shipped packages under a separate root:

./scripts/install.sh ~/.local/lib/kvist
export PATH="$HOME/.local/lib/kvist/bin:$PATH"

Interactive Development

A REPL submission is ordinary Kvist: it is read, macro-expanded, type checked, ownership checked, lowered to Odin, compiled, loaded, and executed as native code. Definitions and supported typed values persist across submissions, and compatible redefinitions update later calls without replaying earlier forms.

The terminal client and editor-neutral JSONL protocol use the same native session. The Emacs client adds source-buffer evaluation, completion, documentation, retained value inspection, source-level stepping, execution traces, conditions and restarts, and attachment to running applications.

See the native REPL guide and Emacs guide.

Odin Interoperability

Kvist imports Odin packages directly:

(import os "core:os")
(import sha2 "core:crypto/sha2")
(import raylib "vendor:raylib")

Procedures, types, constants, enums, multiple return values, allocators, and errors retain their Odin semantics. Kvist and Odin source may also live in the same package and call each other without a wrapper layer.

See the Odin interoperability guide and interop examples.

More Language Features

  • Clojure-style threading, nested destructuring, and structural Data matching.
  • Typed Data validation and decoding into native structs, enums, and arrays, with precise error paths.
  • Explicit conditions and compiled restarts for programmatic or interactive recovery.
  • Parametric polymorphism, overload sets, multiple return values, pointers, custom allocators, and struct-of-arrays storage.
  • Inferred ownership boundaries, source-mapped diagnostics, compilation caches, and lifetime inspection.
  • Shipped packages for native collections, EDN, regular expressions, parallel work, testing, bit operations, strings, and immutable Data.

Tooling

./kvist check examples/language/hello.kvist
./kvist run examples/language/hello.kvist
./kvist repl examples/language/hello.kvist
./kvist test examples/coverage/packages/test-package-tests.kvist
./kvist eval examples/collections/higher-order.kvist '(threaded-total)'
./kvist expand examples/collections/higher-order.kvist '(threaded-total)'
./kvist lifetimes examples/collections/ownership-warnings.kvist

Run ./scripts/smoke.sh for a quick local check.

Platform Support

Kvist is tested on macOS and Linux. The core CLI and representative programs are also tested on Windows, but the complete test suite and shell-based tooling are not yet covered there.

Building Kvist requires an Odin toolchain supported by the host platform. The scripts in scripts/ require a POSIX-compatible shell.

Documentation

License

Kvist is licensed under the MIT License. See LICENSE.

Programs written in Kvist, and Odin code generated from user-authored Kvist source, are not required to use the MIT License merely because they were compiled with Kvist. Code copied from Kvist packages or runtime support remains under its applicable license.

Languages

Odin

84.4%

Clojure

7.9%

Emacs Lisp

4.8%

Shell

2.9%