← Kvist home
Documentation

Tooling#

The kvist CLI compiles Kvist source to Odin and maps Odin diagnostics back to Kvist source where source-map information is available.

Commands#

kvist compile file.kvist -o file.odin
kvist build file.kvist --out dist/app
kvist check file.kvist
kvist frontend-check file.kvist
kvist run file.kvist
kvist test file.kvist
kvist explain KVO004

compile writes generated Odin. build, check, run, and test invoke Odin. frontend-check stops before Odin and is useful for compiler diagnostics; check is the authoritative validation command.

Test selection and memory tracking are optional:

kvist test file.kvist --names test_one,test_two
kvist test file.kvist --track-memory

Evaluation And Expansion#

These commands use the imports and declarations from a source file:

kvist eval file.kvist '(form)'
kvist expand file.kvist '(form)'
kvist macroexpand file.kvist '(form)'

eval compiles and runs the form. expand prints generated Odin. macroexpand prints Kvist after macro expansion. Use eval --check to validate without running and eval --no-print to suppress automatic result printing.

REPL#

Start a persistent session using a Kvist source file as its package context:

kvist repl file.kvist

Forms submitted to the REPL use the normal Kvist compiler. Successful definitions and supported typed values are available to later forms; :reset clears the session and :quit stops it.

Editor clients use the same session through an editor-neutral JSONL protocol:

kvist repl file.kvist --protocol jsonl

See the REPL guide for session behavior, editor integration, and attachment to running applications.

Symbols#

Human-readable documentation:

kvist doc file.kvist symbol

Editor-oriented queries:

kvist lookup file.kvist symbol
kvist complete file.kvist prefix
kvist xref file.kvist symbol
kvist references file.kvist symbol
kvist symbols file.kvist
kvist editor-symbols file.kvist
kvist imported-symbols file.kvist
kvist package-symbols kvist:arr arr
kvist builtin-symbols

Machine-oriented symbol commands print tab-separated rows with declaration kind, name, location, signature, documentation, and source file.

xref finds definitions; references (also available as usages) finds source uses, excluding declaration sites. Each result is a tab-separated row: absolute-file:line:column<TAB>symbol<TAB>source-line. Positions are one-based; columns count UTF-8 bytes, as in compiler diagnostics. An unused symbol produces empty output with a successful exit status.

The search covers .kvist files below the nearest Git root, or the input's directory outside a Git project. Use --root DIR to choose another search scope. Hidden directories, build output, generated .packages trees and symlinked directories are skipped. The input file is always included.

kvist references app/main.kvist service.fetch --root .
kvist usages app/main.kvist value --line 12 --column 9

Without a position, the name is resolved in the file's top-level context. Supply both --line and --column to resolve a particular local binding or shadowed parameter. Imports, aliases, :refer, dot/slash qualification, procedure/macro parameters, let, result-binding conditionals, loops and compact native type annotations are indexed from the parser. Comments, strings, discarded forms and quoted data are excluded; executable unquotes are included. The search does not compile or execute the application.

Editors can pass --source PATH to substitute a read-only buffer snapshot for the input file while retaining its real file identity and import context. Other files are read from disk. Unparseable unrelated files are skipped; an invalid input is an error. This is a source reference index, not full type inference: individual struct fields, enum members, custom macro-introduced bindings, generated macro references and raw Odin bodies are not resolved.

Ownership Inspection#

Show inferred ownership at procedure boundaries:

kvist lifetimes file.kvist

The report marks relevant parameters as borrowed or consumed and results as borrowed, owned, or unknown.

Add --ownership-audit to compilation commands to include conservative ownership warnings that are hidden by default:

kvist check file.kvist --ownership-audit

Warnings have stable codes, readable names, and confidence levels. Formatted output includes both identifiers plus the relevant source line and caret, for example warning[KVO004/overwrite-before-cleanup, conservative]. Editor JSON keeps code, name, and confidence as separate fields. Ownership warnings are suppressed when the compiler proves and emits deterministic native cleanup.

Use either identifier to get the short, stable explanation without compiling a file:

kvist explain KVO004
kvist explain overwrite-before-cleanup
Code Name
KVO001 discarded-owned-result
KVO002 unreleased-owned-local
KVO003 use-after-ownership-transfer
KVO004 overwrite-before-cleanup
KVO005 invalid-borrow-lifetime
KVO006 delete-of-borrowed-value
KVO007 defer-inside-loop
KVO008 automatic-cleanup-not-proven

Packages#

kvist:* imports resolve from:

  1. KVIST_ROOT, when set;
  2. the package root beside an installed bin/kvist;
  3. src/kvist beside a compiler built in this repository.
kvist root

The compiler does not search the current application repository for shipped packages.

Generated Files And Source Maps#

Use --generated to keep generated Odin from build, check, run, or test. compile --map path writes a source map.

kvist compile app.kvist -o build/app.odin --packages
kvist compile app.kvist -o build/app.odin --map build/app.map

--packages writes the generated package tree as well as the root unit. When an imported kvist:* package includes raw Odin sidecar files, commands that write generated Odin copy that package into <output>.packages/kvist-runtime. The generated import points at this copy instead of the compiler installation. Keep the .packages directory beside the generated file when moving or building it elsewhere.

Cache#

The default cache is .kvist-cache. Set KVIST_CACHE_DIR to use another location.

kvist check app.kvist --explain-cache
kvist cache inspect
kvist cache clear app.kvist
kvist cache clear

Set KVIST_NO_COMPILE_CACHE=1 to force fresh translation.

Evaluation output can be saved separately:

kvist eval file.kvist FORM --save NAME
kvist cache list
kvist cache path NAME
kvist cache rm NAME

Timings#

kvist check app.kvist --timings
kvist build app.kvist --timings-json build/timings.json

Timing reports cover Kvist compilation, cache work, Odin phases, and program runtime where applicable.

Emacs#

The Emacs mode provides persistent native evaluation, checking, expansion, documentation, completion, xref, typed value inspection, source-level debugging, execution traces, conditions and restarts, and live-application attachment through the CLI protocol. See the Emacs guide.