Getting Started
Prerequisites
Cure requires:
- Elixir ~> 1.18 and Erlang/OTP (the version compatible with your Elixir)
- Git for cloning the repository
-
Z3 SMT solver (optional) – needed only for refinement type verification. Install via your package manager (
apt install z3,brew install z3, etc.). If Z3 is not present, the compiler skips SMT-backed checks and emits a warning.
Installation
Clone the repository and fetch dependencies:
git clone https://github.com/Oeditus/cure.git
cd cure
mix deps.get
mix compile
Building the escript
Cure v0.15.0 ships with a standalone CLI. Build it with the dedicated Mix task:
mix cure.escript
This compiles the project and produces a cure binary in the project root.
Move it somewhere on your $PATH to use it globally:
cp cure ~/.local/bin/
Verify the installation:
cure version
# Cure 0.15.0
Hello World
Create a file examples/hello.cure:
mod Hello
fn greet(name: String) -> String = "Hello, " <> name <> "!"
fn main() -> Int = 42
Every Cure module starts with mod ModuleName. Functions are declared with fn, typed parameters, a return type annotation, and a body after =. The last expression in a block is its return value.
Compiling
cure compile examples/hello.cure
This runs the full pipeline – lexer, parser, bidirectional type checker, BEAM code generation – and writes a .beam file to _build/cure/ebin/. You can specify a different output directory:
cure compile examples/hello.cure --output-dir ./out
Compile an entire directory at once:
cure compile examples/ --output-dir _build/cure/ebin
Running
cure run examples/hello.cure
This compiles the file, loads the module into the VM, and calls main/0 if it exists. The return value is printed to stdout (unless it is :ok or nil).
Type checking
To type-check without generating BEAM output:
cure check examples/hello.cure
This runs the lexer, parser, and bidirectional type checker, then reports any type errors or warnings. No .beam file is produced.
Compiling the standard library
The standard library is self-hosted – written in Cure under lib/std/. Compile it with:
cure stdlib
Or via the Mix task:
mix cure.compile_stdlib
This compiles all .cure files in lib/std/ and writes the resulting .beam files to _build/cure/ebin/. The stdlib provides 17 modules (~200 functions): Std.Core, Std.List, Std.Math, Std.String, Std.Pair, Std.Show, Std.Io, Std.System, Std.Map, Std.Set, Std.Option, Std.Functor, and more.
Other CLI commands
cure version # Show the Cure version
cure help # Show usage information
cure explain E001 # Show a detailed explanation for error code E001
cure init myproject # Scaffold a new project
cure deps # List dependencies
cure test # Run tests
Editor setup
Neovim (LSP)
Cure includes a Language Server Protocol implementation. Start it with cure lsp (or mix cure.lsp from the project directory). Configure Neovim to use it:
vim.api.nvim_create_autocmd("FileType", {
pattern = "cure",
callback = function()
vim.lsp.start({
name = "cure-lsp",
cmd = { "cure", "lsp" },
root_dir = vim.fs.root(0, { "mix.exs", ".git" }),
})
end,
})
You also need filetype detection. Add to your Neovim config:
vim.filetype.add({
extension = {
cure = "cure",
},
})
The LSP provides:
- Real-time diagnostics (type errors, parse errors, exhaustiveness warnings)
- Hover information (function signatures and types)
- Go-to-definition
- Document symbols (hierarchical module/function outline)
- Code actions (add missing match arms, did-you-mean suggestions)
-
Completion (triggered by
.and:)
MCP server for AI assistants
Cure provides an MCP (Model Context Protocol) server so AI coding assistants can compile, type-check, parse, and analyze Cure code directly:
mix cure.mcp
This starts a JSON-RPC 2.0 server over stdio, compatible with any MCP client (Claude, Warp, etc.). Available tools:
-
compile_cure– compile source, return module name or errors -
parse_cure– parse source, return AST summary -
type_check_cure– type-check source, return errors and warnings -
analyze_fsm– analyze an FSM definition (states, transitions, verification) -
validate_syntax– quick lex + parse validation -
get_syntax_help– get help on a syntax topic -
get_stdlib_docs– get documentation for a stdlib module
Using from Elixir
You can also use Cure as a library from Elixir:
# Compile and load into the running VM
{:ok, module} = Cure.Compiler.compile_and_load(source)
module.my_function(args)
# Compile with type checking
{:ok, module} = Cure.Compiler.compile_and_load(source, check_types: true)
# Compile to disk
{:ok, module, warnings} = Cure.Compiler.compile_file("hello.cure")
Next steps
- Language Guide – full syntax reference
- Type System – bidirectional checking, refinement types, SMT verification
- Finite State Machines – first-class FSMs with compile-time verification