Caution
Although many of the features are working, the code is under a thorough review that may last 3 to 4 months.
Please consider supporting our project so we get ready soon :)
Ipê, pronounced /ip'e/, is a "thick-barked" tree native from South and Central Americas.
The Ipê programming language aims to be a community-centerd and explicitly principled programming language.
It pairs Elm's syntax with Sky's batteries-included runtime — the
standard library, effect system, and application framework (web, API, CLI,
terminal, desktop) that turn a pure-functional language into a full-stack one.
It compiles to readable, rustfmt-clean Rust.
Installation:
curl -fsSL https://raw.githubusercontent.com/arthurmaciel/ipe-lang/main/scripts/install.sh | shScaffold a new project — ipe init writes an ipe.toml, a README.md, and a
working Ipe.Live counter in src/Main.ipe:
ipe init counter # or `ipe init .` to scaffold in the current directory
cd counter
ipe run # serves the counter at http://localhost:8000Prefer to start from scratch? A minimal script program is just:
-- src/Main.ipe
module Main exposing (main)
import Ipe.Prelude exposing (..)
import Ipe.Log exposing (println)
main =
println "Hello from Ipê!"ipe run src/Main.ipe # compile + run in one stepPrefer building from source?
git clone https://github.com/arthurmaciel/ipe-lang
cd ipe-lang
cargo build --release`.- Elm syntax — pure functions, Hindley–Milner type inference, exhaustive
case, immutable data. Nonull, no runtime exceptions. - Sky's batteries-included runtime — Live applications (SSR + real-time), typed HTTP,
SQL databases, auth, email, cache, pub/sub, and WebSockets, all behind a
single
Task Error aeffect boundary. - Rust compiler — the compiler itself is written in Rust: fast, parallel, memory-safe.
- Rust backend — emits readable Rust.
- Incremental compilation — a salsa-backed query engine;
ipe watchrecompiles only what changed. - Static compilation —
ipe build --staticproduces a fully-static musl single binary. Copy it anywhere and run — no runtime, no dependencies. - No authored abrupt failure — the compiler's and runtime's own Rust carries
no
panic!,unwrap,expect,assert!, or indexing panic. Every failure is a typedResultor a diagnostic.
One language, five ways to ship. Pick the entry point that matches your app.
| Shape | Entry point | Use it for | TEA |
|---|---|---|---|
Ipe.Live |
Live.app |
Web apps — server-rendered HTML, real-time SSE patches, sessions | ✓ |
Ipe.Http.Server |
Server.listen |
Headless HTTP / JSON APIs | |
Ipe.Cli |
Task.run |
One-shot tools and cron jobs | |
Ipe.Tui |
Tui.app |
Terminal UIs | ✓ |
Ipe.Webview |
Webview.app |
Native desktop apps | ✓ |
The three ✓ shapes follow The Elm Architecture
(init / update / view / subscriptions) — and share the same
Ipe.Ui view code, so one view renders on web, terminal, and desktop.
See examples/ for a program of each shape.
Every effect in Ipê flows through a capability-tagged kernel, so the compiler can
tell you exactly what a program is allowed to do — network, filesystem, env,
subprocess, clock, random, native-ffi — from its code alone, with nothing to
declare. ipe capabilities <entry> prints that inferred set as a human report by
default; --plain gives the bare names, one per line, for a script:
$ ipe capabilities --plain examples/sky/02-go-stdlib/src/Main.ipe
network
clock
The set is generated, not hand-written, and cannot drift: a program that reaches
a new effectful kernel gains the matching capability automatically. native-ffi
appears whenever the program crosses into Rust. code, which is opaque to the
inference and the one place effects can escape the model.
See Capabilities for the full model — the eight
capabilities, how inference works, and how native code declares and is sandboxed.
Every command is human-friendly by default; data commands take --plain and
--json for scripts — see CLI output.
ipe lsp speaks JSON-RPC over stdio — type-directed completion, go-to-definition,
find-references, rename, formatting, code actions, semantic tokens, and more.
See docs/editor-integration.md for setup
instructions covering Helix, Neovim, VS Code, Emacs (lsp-mode and Doom Emacs),
and Zed.
ipe build --static produces a fully-static musl binary — zero runtime
dependencies, copy and run anywhere.
# Prerequisite (once):
rustup target add x86_64-unknown-linux-musl
sudo apt-get install musl-tools # or equivalent on your distro
# Build a static binary (x86_64 Linux, dlmalloc allocator — the default):
cd examples/01-hello-world
ipe build ipe.toml --out out/rust --static
cd out/rust
cargo build --release --target x86_64-unknown-linux-muslThe emitted .cargo/config.toml sets +crt-static automatically; no extra
RUSTFLAGS are needed.
Allocator options (--allocator <name>):
| Name | Default | Notes |
|---|---|---|
dlmalloc |
yes | pure Rust, no C toolchain beyond musl |
mimalloc |
C opt-in; needs a musl-capable C compiler | |
system |
musl's malloc; requires --allow-slow-allocator |
Supported targets:
| Target | Status |
|---|---|
x86_64-unknown-linux-musl |
fully supported, CI-verified |
aarch64-unknown-linux-musl |
wired, pending toolchain confirmation (CI: continue-on-error) |
The aarch64 target is structurally complete — the variant exists, the CI job
runs, and cross-verification via qemu-user-static is scripted — but the CI
job is marked continue-on-error until a musl-capable AArch64 C linker is
confirmed available on the runner. Remove continue-on-error from
.github/workflows/static.yml linux-static-arm64 once the job turns green.
Contributions are very welcome!
There are 4 main forms to support our project. They are listed in order of need at the current moment:
I'd love to spend more time developing Ipê and also buying AI tokens to test battle the code. If you like these idea, please support Ipê's development. Thank you!
The most valuable pull requests are security/soundness fixes — a mis-compilation, a panic on valid input, an unsound emit or security brech.
Every PR must be human-reviewed. Unfortunately there is not enough time to
review AI-only reviewed code. Sorry for that!
Even if you can't propose any code yet, please report any bugs you find!
