Skip to content

Repository files navigation

Morrow logo

Morrow

Readable code. Native programs.
Explore the Morrow programming language: statically typed, functional, with Python-like syntax.

Project home · Documentation

Morrow brings immutable values, pattern matching and explicit errors to readable, indentation-based code. Write Morrow, check it before execution, and compile it to a native executable with a Rust compiler and runtime. The same typed application can run as native server actors and as a reactive WebAssembly browser client, with WebSocket updates and offline continuity.

fn greet(name: String) -> String:
    "Hello, {name}!"

fn main():
    println(greet("Morrow"))

Early preview, with a working Rust implementation. The compiler, runtime, language server and repository tools are Rust. Native execution and release installation are verified on macOS ARM64 and Linux ARM64. Syntax and APIs are still evolving; see what is verified and what remains, or compare the implemented language across targets.

Why Morrow?

  • Code that reads clearly. Significant indentation, inferred types, immutable bindings and expressions that return values keep everyday programs direct.
  • Errors you can see. Option, Result and exhaustive pattern matching make absence and failure explicit. The compiler checks that results are handled.
  • Useful tools together. A formatter, REPL, source tests, documentation generator and language server ship with the compiler.
  • Native programs. Cranelift generates machine code and the Rust runtime supplies memory management and services. Running a compiled program does not require the Morrow compiler; platform system libraries still apply.
  • A growing full-stack path. Compile Morrow functions to WebAssembly and try a collaborative checklist with local browser interaction, WebSocket updates and cached offline viewing. Its Rust server can ship as one static Linux binary.

The direction is a practical language for command-line tools and applications: readable code, predictable behavior and a useful standard library. The design describes that larger vision; the roadmap tracks its implementation. The full-stack direction combines supervised native actors with a reactive Morrow WebAssembly client over typed WebSocket connections. The working web preview proves the first integration; the architecture defines the remaining language, supervision and scaling work.

Try it

You need rustup and a host compiler/linker: Xcode command-line tools on macOS, or GCC/Clang with the platform development libraries on Linux.

git clone https://github.com/morrow-lang/morrow.git
cd morrow
cargo xtask build --release
./bin/morrow run examples/tiny_cli.mr
./bin/morrow build examples/tiny_cli.mr -o hello
./hello
./bin/morrow run examples/language_tour.mr

The example prints hello, morrow. run compiles and executes in one step; build leaves an executable you can run directly. The language tour combines traits, compile-time constants, immutable sets, typed JSON and deferred cleanup in one small program.

The repository selects its pinned Rust nightly automatically through rust-toolchain.toml; Cargo uses the checked-in dependency lock. Mise is optional. See the build guide for prerequisites and platform details.

Try the web preview

With the Rust prerequisites above, install the browser build tools once:

rustup target add wasm32-unknown-unknown
cargo install wasm-bindgen-cli --version 0.2.128 --locked
cargo xtask web-build
MORROW_WEB_ACCESS_KEY='replace-with-a-long-random-secret' ./dist/morrow-web

Open http://127.0.0.1:3000, sign in with your chosen key and try two browser windows. Add tasks, toggle completion and filter locally. After the first online visit has cached the application, offline reload preserves the last confirmed list and your draft. Shared changes require a connection.

The binary embeds the HTML, CSS, browser WASM, generated bindings and Rust service worker. The shared Morrow application owns the domain model, local model, event updates and keyed view. Its native room actor owns authoritative state. Rust provides the DOM, storage, authenticated transport and a rooted native embedding boundary; the shipped server contains no compiler or interpreter.

Set MORROW_WEB_DATA_DIR=./morrow-data to checkpoint acknowledged room changes and recover them after a restart. Authentication and command namespaces start fresh; uncertain commands are never blindly replayed into a new incarnation.

Rooms run on independent actor worker threads: by default, up to four available CPU cores. Set MORROW_WEB_WORKERS=1 through 32 to choose the worker count. Authentication stays responsive while a room executes, and admission limits remain shared across workers. See the worker contract for room placement, revocation and durable-write behavior.

Connect multiple servers: morrow-web --cluster-init creates private node bundles; MORROW_WEB_CLUSTER enables authenticated TLS routing to fixed room owners. Browsers keep their normal automatic WebSocket connection to a gateway. The three-node guide includes setup, delivery guarantees and the 10,000-mutation stress scenario. Membership is fixed; partitions do not trigger ownership takeover or replay uncertain mutations.

The live wire standard is protobuf over binary WebSocket, with protobuf over mutual TLS between servers. The measured protocol comparison explains the choice, the explicit legacy JSON browser path and migration gates. HTTP APIs, offline records and checkpoints keep their separate JSON formats.

See the web guide for Linux static builds, authentication, offline behavior and the exact preview boundary.

Open /admin after signing in to inspect uptime, resident memory, workers, rooms, connections and resource limits. The system dashboard also provides authenticated JSON snapshots and configured versus connected peers.

Explore resilience

Run the actual protocol and native Morrow actors under reproducible faults and virtual time, then replay the result:

cargo xtask simulate --seed 42 --steps 3000 --days 30 --json > scenario.json
cargo xtask simulate --replay scenario.json
cargo xtask simulate --actors --seed 42 --steps 5000

The demo and simulation guide combines native supervision, the offline WASM draft preview and deterministic failure testing. Simulated time measures the scenario's clock; it is not a production-uptime claim.

Available today

  • Immutable bindings, inferred types and functions that return their last expression.
  • Integers, floating-point values, strings, collections, records, tagged sums, newtypes and finite unions.
  • Exhaustive pattern matching, Option, Result, ? and checked error handling.
  • Modules, closures, generic functions and static traits with defaults, explicit bounds and structural derivation.
  • Derived and custom JSON codecs, including nested union discrimination, precise error paths and shared resource limits.
  • Immutable Sets, compile-time constants, and explicit native foreign functions with checked ABI types.
  • Native services for files, processes, HTTP clients, SQLite, terminal widgets and bounded actor execution with suspended cleanup.
  • Interactive actors and deterministic replay for testing mailboxes, timeouts, restarts and cancellation without real-time sleeps.

Follow the language guide, explore examples, or read the standard-library reference.

What the experiments show

The paired list-optimization measurements show a 2.98–3.71× improvement through bounded callback inlining, direct list loops and optimized native emission, following the earlier GC bookkeeping improvement. The latest native run on one Apple M4 measures 10,000 immutable updates of a 256-entry model at 8.37 ms, and 100,000 at 60.31 ms. Optimized Rust takes 3.37 / 11.54 ms. Immutable aliases and checked fault behavior are preserved.

The model uses approximately 3.5 MiB RSS; its macOS executable is 567,656 bytes. A subsequent arithmetic optimization reduces twenty million scalar steps from 76.60 to 66.57 ms, against Rust's 57.35 ms in the same run. Exposing safe constant divisors and keeping integer tail-loop parameters in registers work together; the measured arithmetic gap to Rust falls from about 34% to 16%. Building the small source takes 42.48 ms. Native programs use Cranelift opt_level=speed, independently of the compiler's own Rust build profile. Rust remains faster on these workloads; broader inlining, collection layout and allocation remain work.

These measurements were recorded under the name Fern before the 2026-09-15 rename. See the current benchmark commands for new runs.

The original Fern/Rust/TypeScript comparison also measures Bun 1.4.2 and TypeScript 6.0.2, retaining the earlier unoptimized Fern baseline. Bun was not rerun for the latest optimization. These are specific whole-process experiments, not a universal language ranking.

A fresh Elixir/BEAM comparison uses Elixir 1.20.4 and OTP 29.0.6 with JIT enabled. For 100,000 immutable updates, Morrow takes 63.29 ms per workload in a ten-repeat process; Elixir takes 184.27 ms with tuples or 207.23 ms with structs even when VM startup is excluded. This supports Morrow's native performance direction. Actor throughput, scheduler fairness and fault recovery against BEAM remain unmeasured.

The compiler experiments show useful defaults: required Result handling, exhaustive matches and labels for ambiguous arguments. Rust and configured TypeScript provide strong alternatives. They do not establish a developer productivity advantage. Morrow's current List.get still faults out of bounds; typed errors do not yet cover every runtime failure. The report retains raw samples, first-launch outliers, configuration details and runnable sources.

Compiler tools

./bin/morrow check source.mr
./bin/morrow fmt source.mr
./bin/morrow test source.mr
./bin/morrow doc source.mr --html
./bin/morrow doc src --site docs-site --extras README.md --open
./bin/morrow repl
./bin/morrow lsp

Replace source.mr with your program. The language server provides diagnostics, completion, navigation, formatting, rename and more over standard input/output. Configure your editor to launch morrow lsp using the installed executable or its absolute path. See the compiler guide for command details and the inspection tools.

Documentation is written next to the code with @moduledoc and @doc, and examples inside it run as tests. morrow doc --site renders modules and Markdown guides into a searchable site with cross-references; cargo xtask docs builds this repository's own site, including the Rust API reference. See writing and publishing documentation.

Our implementation stance

Morrow-owned implementation and development tooling stay in Rust, organized as a Cargo workspace. We prefer safe ownership, explicit resource limits and small, documented unsafe boundaries where native ABI and operating-system access require them. A Rust-owned tracing collector manages native Morrow values, with isolated actor payload heaps and copied messages. Compiler root frames are explicit; conservative scanning remains while precise-root coverage is completed. Ordinary Morrow code does not require borrow checking or lifetime annotations.

We prefer native Rust dependencies and permit maintained Rust wrappers around third-party native libraries. SQLite uses rusqlite; the native HTTP client uses ureq and rustls. A Rust implementation does not imply that every transitive dependency is Rust. Dependency notices document the shipped libraries.

Editor support uses the Rust LSP and the compiler's parser. Tree-sitter integration has been removed. Cargo and xtask own the build, checks and distribution workflow. Browser interop JavaScript is generated during the build; the browser host, service worker and build pipeline are authored in Rust.

Status and next steps

The 2026-09-12 Rust migration acceptance record covers both ARM64 hosts: over 1,750 Rust tests per platform, 305 native-output fixtures, compatibility and fuzz checks, optimized runtime/ABI tests, and real archive relocation, installation and source-test execution. Formatting and Clippy are part of the required quality gate. That record predates the new actor-heap and web work. Fresh macOS ARM64 checks passed; Linux ARM64 completed equivalent coverage across resumed runs after a storage interruption. The web guide records the exact native scope and real-browser checks, including offline worker restart, cache integrity, mobile layout and static ARM64 server execution. The application and worker acceptance record adds the complete 1,890-test gate, actor lifecycle/progress checks and measured static servers of 2.75 MiB (ARM64) and 3.06 MiB (x86-64).

Morrow is ready to explore, build small programs with and contribute to. It remains an early preview: general actor preemption, generalized supervision, work stealing, dynamic cluster membership, replicated failover, remote language PIDs and a general application packaging API remain open. The current checklist executes its complete typed model/update/view and native actor path, with optional durable room checkpoints. WASM supports bounded records, tagged sums, lists, tuples, Option/Result, UTF-8 strings, closures, maps, sets, ranges, iteration, deferred cleanup and structural unions with precise tracing and rooted host handles; see portable language support. Native services remain separate capabilities. Static traits, custom JSON codecs, compile-time constants and Sets work through the checked language pipeline. Broader SQL APIs, x86-64 native-language acceptance and source debugging remain open. The REPL supports a smaller host service surface than native programs. The Rust rewrite is complete; the language roadmap continues.

Install or contribute

cargo xtask install "$HOME/.local"

Add $HOME/.local/bin to your PATH to use morrow directly. Installation builds release components. To remove them, run cargo xtask uninstall "$HOME/.local".

For development and packaging:

cargo xtask check
cargo xtask package

check builds the components and runs formatting, linting, Rust tests and native acceptance. package creates a verified host archive and checksum in dist/. The release bundle includes morrow, the Rust test supervisor, the Rust runtime archive, its package marker and license notices. Keep these components together when moving an installation.

Directory Responsibility
crates/morrow Compiler, CLI, formatter, REPL, docs and LSP
crates/morrow-runtime Native values, collector and services
crates/morrow-runtime-native Compiled-program startup
crates/morrow-json Shared bounded JSON implementation
crates/morrow-web-protocol Authenticated command/revision contracts and application transitions
crates/morrow-web-app Compiled Morrow actor embedding and durable room checkpoints
crates/morrow-web Authenticated HTTP/WebSocket preview server and embedded assets
crates/morrow-browser Rust browser host, generic keyed DOM and Morrow model handles
crates/morrow-browser-worker Rust service worker for cached offline loading
crates/morrow-test-supervisor Native test capture and process cleanup
xtask Build, checks, packaging and installation

The contribution guide requires tests before behavior changes. See MORROW_STYLE.md for Rust safety and resource-bound conventions. The documentation index connects language references, contracts and acceptance reports.

Released under the MIT License.