DEV Community

Alex Spinov
Alex Spinov

Posted on

MoonBit Has a Free API: A Language Designed for WebAssembly With Rust-Level Performance

MoonBit is a programming language designed from the ground up for WebAssembly. It combines Rust-level performance with a developer experience closer to Go or TypeScript.

Why MoonBit Matters

Compiling to WebAssembly is an afterthought for most languages. MoonBit was designed for Wasm from day one — its type system, runtime, and compiler all optimize for the Wasm execution model, producing binaries 10x smaller than Rust's.

What you get for free:

  • WebAssembly-first design (10x smaller than Rust Wasm output)
  • Fast compilation (much faster than Rust)
  • Pattern matching and algebraic data types
  • Structural typing with traits
  • Built-in package manager (moon)
  • IDE support with Language Server Protocol
  • No garbage collector needed for Wasm GC targets

Quick Start

# Install
curl -fsSL https://cli.moonbitlang.com/install/unix.sh | bash

# Create project
moon new my-project
cd my-project

# Run
moon run

# Build Wasm
moon build --target wasm

# Test
moon test
Enter fullscreen mode Exit fullscreen mode

The Basics

fn main {
  let name = "MoonBit"
  println("Hello from \{name}!")

  let numbers = [1, 2, 3, 4, 5]
  let doubled = numbers.map(fn(n) { n * 2 })
  println(doubled.to_string())

  let result = divide(10, 3)
  match result {
    Ok(value) => println("Result: \{value}")
    Err(msg) => println("Error: \{msg}")
  }
}

fn divide(a : Int, b : Int) -> Result[Int, String] {
  if b == 0 {
    Err("division by zero")
  } else {
    Ok(a / b)
  }
}
Enter fullscreen mode Exit fullscreen mode

Enums and Pattern Matching

enum Shape {
  Circle(Double)
  Rectangle(Double, Double)
  Triangle(Double, Double, Double)
}

fn area(shape : Shape) -> Double {
  match shape {
    Circle(r) => 3.14159 * r * r
    Rectangle(w, h) => w * h
    Triangle(a, b, c) => {
      let s = (a + b + c) / 2.0
      @math.sqrt(s * (s - a) * (s - b) * (s - c))
    }
  }
}

fn main {
  let shapes : Array[Shape] = [Circle(5.0), Rectangle(3.0, 4.0)]
  for shape in shapes {
    println("Area: \{area(shape)}")
  }
}
Enter fullscreen mode Exit fullscreen mode

Structs and Methods

struct User {
  name : String
  age : Int
  email : String
}

fn User::new(name : String, age : Int, email : String) -> User {
  { name, age, email }
}

fn greet(self : User) -> String {
  "Hello, \{self.name}! You are \{self.age} years old."
}

fn main {
  let user = User::new("Alice", 30, "alice@example.com")
  println(user.greet())
}
Enter fullscreen mode Exit fullscreen mode

Traits

trait Printable {
  to_display(Self) -> String
}

fn to_display(self : User) -> String {
  "User(\{self.name}, \{self.age})"
}

fn print_all[T : Printable](items : Array[T]) -> Unit {
  for item in items {
    println(item.to_display())
  }
}
Enter fullscreen mode Exit fullscreen mode

Error Handling

type! ParseError {
  InvalidFormat(String)
  OutOfRange(Int)
}

fn parse_age(input : String) -> Int!ParseError {
  let n = try {
    @strconv.parse_int!(input)
  } catch {
    _ => raise InvalidFormat("not a number: \{input}")
  }
  if n < 0 || n > 150 {
    raise OutOfRange(n)
  }
  n
}

fn main {
  try {
    let age = parse_age!("25")
    println("Age: \{age}")
  } catch {
    InvalidFormat(msg) => println("Format error: \{msg}")
    OutOfRange(n) => println("Out of range: \{n}")
  }
}
Enter fullscreen mode Exit fullscreen mode

Wasm Size Comparison

Language Hello World Wasm Performance
MoonBit ~5KB Excellent
Rust ~50KB Excellent
Go ~2MB Good
AssemblyScript ~15KB Good

Useful Links


Building WebAssembly applications? Check out my developer tools on Apify for ready-made web scrapers, or email spinov001@gmail.com for custom solutions.

Top comments (0)