A high-level language that transpiles to Rust. Copper aims to keep Rust's
performance while giving you a syntax that reads like a modern scripting
language — string interpolation, optional chaining, ternaries, and JS-style
loop / match / closure forms — backed by cforge, the Copper toolchain.
import * from std.io
name = input!("What's your name?")
println!("Your name is $name")
There's also a native installer — built with MUI (mocida's declarative UI; no web stack, no Tauri), Windows-only for now — that wraps the script below in a clickable form.
See docs/INSTALL.md for the full guide. TL;DR — one
cross-platform Python installer (needs Python 3.7+):
python scripts/install.pyOn Windows you can also double-click scripts\install.bat; on Unix run
bash scripts/install.sh. Both just forward to install.py. The installer
auto-detects admin / root and picks a global or per-user install accordingly.
cforge -c -i ./src| Flag | Full name | Description | Example |
|---|---|---|---|
-i |
--input |
Input file or directory | cforge -c -i main.crs |
-o |
--output |
Output directory | cforge -o ./build |
-t |
--target |
Cross-compile target | cforge -t windows |
-c |
--compile |
Compile (no run) | cforge -c -i main.crs |
--clean |
Clean the output directory | cforge --clean |
|
-V |
--verbose |
Verbose output | cforge -V run main.crs |
-v |
--version |
Print version (with build date for pre-releases) | cforge -v |
cforge run ./main.crscforge run (no arg) defaults to ./main.crs in the current directory.
class Greeter {
name: String
Greeter(name: String) {
self.name = name
}
void hello(self) {
println!("Hello, {}!", self.name)
}
}
Greeter::new("Brian".to_string()).hello()
The class lowers to a Rust struct + impl. The constructor (same name
as the class) becomes pub fn new(...) -> Self, and methods declared as
void name(self) become pub fn name(&self). Use cforge run main.crs
to see it print Hello, Brian!.
mut count = 0
loop {
count++
if count == 3 { break }
}
mut user: Option<User> = Some(User { name: "Brian".to_string(), age: 30 })
mut age = user?.age // Some(30)
mut grade = score >= 9 ? "A" : "B"
match n {
0 => 0,
1 | 2 | 3 => 1,
n if n < 0 => -1,
_ => 2
}
See examples/ for runnable demos of each feature.
Rust's standard library is powerful but verbose for everyday scripting tasks
(reading a line of input, sleeping, getting the current time, running a shell
command). Copper ships an embedded cstd module — import what you need and
the compiler injects only the helpers you used:
import { input, read_int, sleep_ms, now_ms, run, exit, env, exists } from cstd
name = input("Your name? ")
age = read_int("Age: ")
println!("Hello $name ($age)")
started = now_ms()
sleep_ms(100)
println!("slept ~{}ms", now_ms() - started)
println!("HOME = {}", env("HOME"))
println!("ls -> {}", run("ls"))
Available functions: input, readln, read_int, read_float, to_int,
to_float, trim, split, join, exit, die, panic_if, sleep_ms,
now_ms, env, args, read_file, write_file, append_file, exists,
is_file, is_dir, list_dir, run, rand_int.
The library lives in std/cstd.crs (Copper) plus
std/cstd_native.rs for the few helpers Copper's
transpiler can't yet express cleanly (multi-line method chains, &[T]
slice types, cfg!(target_os=...)). Editing either file and rebuilding
cforge ships the change.
copper-lang/
├── src/ # Compiler source (Rust)
├── examples/ # Runnable samples (copper/ → .crs, mui/ → .mui/.crm)
├── scripts/ # Python tooling: install / build / cleanup / diagnose / uninstall / hooks
├── docs/ # INSTALL.md and other guides
├── std/ # Copper standard library (.crs)
├── lson/ # LSON parser binaries (per-OS)
├── assets/ # Logos
├── main.crs # Default file used by `cforge run` with no argument
├── properties.kson # Project metadata + dependencies
├── Cargo.toml # Rust crate definition (cforge)
├── build.rs # Stamps the build date into pre-release versions
└── README.md
cforge run examples/copper/loops.crs # loop / while / for / break / continue
cforge run examples/copper/interpolation.crs # "Hello $name", "${expr}"
cforge run examples/copper/collections.crs # vec literals, closures, ?
cforge run examples/copper/matching.crs # match arms, if let, while let
cforge run examples/copper/optional.crs # `?.` optional chaining
cforge run examples/copper/ternary.crs # `cond ? a : b`
cforge run examples/copper/cstd.crs # built-in stdlib (input, sleep, env, ...)
cforge run examples/copper/unsafe.crs # `unsafe func` and `unsafe { ... }` blocks
# MUI examples (need mui-dev on PATH):
cforge run examples/mui/hello/hello.mui
cforge run examples/mui/counter/counter.mui
cforge run examples/mui/keyboard/keyboard.mui # onKeyInput — keyboard events + println debug
cforge run examples/mui/app/app.muiStatus of the toolchain. Checked = working today.
Language (cforge)
- Core transpile pipeline (
.crs→ Rust),cforge run/-c - Variables, functions, classes/structs/impl, imports
- Loops,
match(guards/_/|),if let/while let - Optional chaining
?., ternary?:, string interpolation"${expr}" -
unsafeblocks + functions, raw pointers, generic return types -
cstdstandard library,.rsinterop - CalVer versioning + git commit hash in
--version - Generics in parameters (
func<T> name(arg: T),struct S<T>) - Fix
println(var)/println("${x}")→ valid Rust (needs a string-literal first arg) -
?:ternary inside${…}interpolation (captured opaque before the rewrite) -
&[T]slice params incstd(tokenized as a vec literal)
MUI front-end (.mui / .crm)
-
cforge run x.muidev render (viamui-dev) -
cforge -c [-r] x.muicodegen + native build (viamui-codegen) - Component import/reuse, same-file components,
app { }config + bundles -
onKeyInputkeyboard handlers (event.key,=/+=/-=/++,println!debug) - Codegen feature parity with the runtime (string signals, conditional text/color, reactive
if/for, native Stack styling) - Folder-input autocomplete without losing focus on rebuild
Installer
- MUI-based native installer (no Tauri/web), real
cforgeinstall (PATH, scope, dedupe) -
lsonas a git submodule, auto-built on first run - Signed installer artifact + CI release packaging
Pull requests are welcome. Please open an issue first for non-trivial changes so we can discuss the approach.
After cloning, activate the repo's git hooks once so commits and pushes run the same lint gates CI does:
python scripts/hooks.pyThis sets core.hooksPath to .githooks/. From then on:
pre-commitrunscargo fmt --checkandcargo clippy --all-targets -- -D warningspre-pushrunscargo test
Bypass with --no-verify only when you have to (the same checks fail in CI
afterwards).

