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/am-kantox/cure-lang.git
cd cure-lang
mix deps.get
mix compile

Building the escript

Cure v0.33.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.33.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 ships 33+ modules (Std.Core, Std.List, Std.Math, Std.String, Std.Pair, Std.Show, Std.Io, Std.System, Std.Map, Std.Set, Std.Option, Std.Functor, Std.Equal, Std.Refine, Std.Match, Std.Proof, Std.Gen, Std.Iter, Std.Access, Std.Json, Std.Http, Std.Actor, Std.Process, Std.Supervisor, Std.App, Std.Time, Std.Regex, Std.CRDT, and more). As of v0.29.0 every module carries a module-level ## Examples block; browse the rendered docs at cure-lang.org/stdlib or run cure doc locally to produce the same two-pane layout under _build/cure/doc/.

Other CLI commands

cure version              # Show the Cure version
cure help                 # Show usage information
cure explain E011         # Show a detailed explanation for an error code
cure new myproject --lib  # Scaffold a new library project
cure new myapp --app      # Scaffold a new OTP app (v0.26.0): app + sup
                          # root, matching [application] / [release] in
                          # Cure.toml
cure deps                 # List dependencies
cure deps tree            # Inspect dependency graph
cure deps update          # Refresh Cure.lock
cure test --doctests      # Run tests, including doctests
cure test --cover         # Emit _build/cure/cover/index.html
cure release              # Build a bootable BEAM release under
                          # _build/cure/rel/<name>/ (v0.26.0)
cure release --include-erts # Bundle ERTS into the release
cure repl                 # Raw-mode REPL with syntax highlighting,
                          # persistent history, Ctrl+R reverse search,
                          # Tab completion, :history / :bench / :time / :save
cure watch lib/           # Recompile / check / test on every save
cure fmt lib/             # Format Cure sources
cure bench                # Run bench/**/*.cure benchmarks
cure doctor               # Environment + project + source health report
cure fix                  # Apply safe project-wide rewrites
cure publish --dry-run    # Preview what `cure publish` would upload
cure publish --hex        # Build a Hex-compatible tarball
cure search <query>       # Search the registry
cure info <name>[:ver]    # Inspect a package manifest
cure keys generate <h>    # Generate an Ed25519 signing keypair

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, pattern coverage)
  • Hover information with function signatures, inferred effects, unification traces, and hole goals
  • Go-to-definition, prepareRename and rename
  • Document symbols (hierarchical module / function outline)
  • Workspace symbols
  • Code actions (add missing match arms, did-you-mean suggestions)
  • Completion (triggered by . and :)
  • Inlay hints, signature help, code lenses, semantic tokens
  • Formatting routed through the round-trip-tested Cure.Compiler.Printer

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
&lbrace;:ok, module&rbrace; = Cure.Compiler.compile_and_load(source)
module.my_function(args)

# Compile with type checking
&lbrace;:ok, module&rbrace; = Cure.Compiler.compile_and_load(source, check_types: true)

# Compile to disk
&lbrace;:ok, module, warnings&rbrace; = Cure.Compiler.compile_file("hello.cure")

Next steps

  • Language Guide -- full syntax reference
  • Type System -- bidirectional checking, refinement types, SMT verification
  • Dependent Types -- Sigma, Pi, equality, implicit arguments, holes, totality
  • Finite State Machines -- first-class FSMs with compile-time verification
  • Actors -- typed supervision trees, the Melquiades Operator, actor and sup containers (v0.25.0)
  • Applications -- first-class OTP applications and BEAM releases, the app container, Cure.toml [application] / [release] sections, cure release, Std.App (v0.26.0)
  • REPL -- the raw-mode REPL (v0.24.0): key bindings, meta-commands, themes, history, reverse search
  • Standard Library -- auto-generated docs for every Std.* module, extracted from .cure sources with the same two-pane layout cure doc produces locally (v0.29.0)
  • Tooling -- CLI reference including cure doc (ExDoc-like two-pane layout, [doc] config, --title / --main / --extras flags), LSP, and MCP
  • docs/DOC.md -- on-disk reference for the cure doc pipeline, Cure.Doc.Markdown, placeholder interpolation, and the REPL Markdown renderer (v0.29.0)