Getting Started
OverviewLanguage GuideFull Reference
Book
Table of ContentsIntroductionPrefaceGetting StartedLanguage TourOwnershipErrorsConcurrencyStdlibNetworkingDataPackagesSpeed & SafetyCross-PlatformToolingCookbookAppendix
Reference
Standard LibraryKeywordsPerformanceSecurityBuilt-in FunctionsStatusDebuggingABI
How-To
Getting StartedHTTP APIsErrorsPackagesConcurrencyMemoryWASITestingRelease Builds
Project
RoadmapVisionChangelogContributing

2. Getting Started

This chapter walks you through installing Mako, creating your first project, understanding the project structure, and setting up your editor.

System requirements

To build and run Mako programs you need:

Optional dependencies for full standard library support:

Installing Mako

From a source checkout:

make install

This installs the mako binary to ~/.local/bin/mako and runtime headers to ~/.local/share/mako/runtime. Make sure ~/.local/bin is in your PATH.

Alternatively, use the install script directly:

./scripts/install.sh

Verify the installation:

mako version
# mako version mako0.1.0 darwin/arm64

The --version flag produces the same output:

mako --version
# mako version mako0.1.0 darwin/arm64

For verbose output including the git commit (when available):

mako version -v

Building from source

If you want to build from the repository:

git clone https://github.com/mako-lang/mako.git
cd mako
cargo build --release

You can run the compiler directly without installing:

cargo run --release -- version
cargo run --release -- run examples/hello.mko

Then install when ready:

make install

Windows (PowerShell)

cargo build --release
.\scripts\install.ps1
mako version

On Windows, ensure that clang is available in your PATH. The easiest way is to install the LLVM toolchain from the official LLVM releases page.

Runtime path override

The compiler looks for runtime headers at $PREFIX/share/mako/runtime. If you installed to a non-standard location, set the MAKO_RUNTIME environment variable:

export MAKO_RUNTIME=/opt/mako/runtime

The mako doctor command

After installation, run mako doctor to verify your environment is correctly configured:

mako doctor

This checks:

If anything is misconfigured, mako doctor prints actionable guidance on how to fix it.

Your first program

Create a file called hello.mko:

fn main() {
    print("hello from mako")
}

Run it:

mako run hello.mko
# hello from mako

That is the entire workflow. mako run compiles the source to C, invokes clang, and executes the resulting binary in one step.

Creating a project with mako init

For anything beyond a single file, use mako init to scaffold a project:

mako init myapp --name myapp
cd myapp

This creates:

myapp/
  mako.toml      -- project manifest
  main.mko       -- entry point

Run the generated project:

mako run main.mko

Backend service scaffold

For an HTTP-oriented service layout:

mako init mysvc --backend
cd mysvc
mako run main.mko

This generates a project with HTTP server boilerplate and route handlers.

Workspace scaffold

For a project with multiple members (library + application):

mako init myws --workspace
cd myws
mako check .
mako run -p app

Project structure: mako.toml

The mako.toml file is the project manifest. It declares the project name, version, dependencies, and build configuration:

[package]
name = "myapp"
version = "0.1.0"

[dependencies]
# path dependencies
utils = { path = "../utils" }

# registry dependencies (when available)
# json = "1.0"

[build]
# parallel compilation jobs
jobs = 8

When you run mako build main.mko in a directory with a mako.toml, the binary name is derived from the package name.

The build and run cycle

Command What it does
mako run file.mko Compile and execute in one step
mako check file.mko Type-check without producing a binary (fast)
mako build file.mko Compile to a native binary
mako build --release file.mko Optimized build (-O3 -flto)
mako build -j 8 file.mko Parallel object compilation
mako test examples/testing Run the test suite
mako fmt file.mko Format source to canonical style

Incremental compilation

Incremental compilation is on by default. The compiler caches intermediate artifacts and only recompiles translation units that have changed. This makes the edit-compile-run loop fast even for larger projects.

Release builds

For production deployment, always use --release:

mako build --release main.mko

This enables -O3 optimization and link-time optimization (-flto), producing a smaller, faster binary. The resulting binary is a single statically-linked executable suitable for deployment anywhere.

A more complete first program

Here is a slightly more involved example showing functions, types, and control flow:

fn main() {
    print("Fibonacci calculator")
    let n = 10
    print_int(fib(n))

    let mut sum = 0
    for i in range n {
        sum = sum + fib(i)
    }
    print_int(sum)
}

fn fib(n: int) -> int {
    if n <= 1 {
        return n
    }
    return fib(n - 1) + fib(n - 2)
}
mako run fib.mko
# Fibonacci calculator
# 55
# 88

Working with multiple files

Most projects need more than one file. Mako handles this with import -- you point at a file, and its functions become available. When you mako run main.mko, the compiler automatically pulls in everything that's imported.

Basic file import

Start with two files side by side:

// lib.mko
fn add(a: int, b: int) -> int {
    return a + b
}

fn greet(name: string) -> string {
    return "hi " + name
}
// main.mko
import "./lib.mko"

fn main() {
    print_int(lib_add(2, 3))
    print(lib_greet("mako"))
}
mako run main.mko
# 5
# hi mako

Without an alias, the imported file's functions merge into your scope directly. By convention, prefix them (e.g. lib_add) to avoid collisions.

Aliased imports

Give the import a name and access everything through that namespace:

// main.mko
import "./lib.mko" as lib

fn main() {
    print_int(lib.add(2, 3))
}

This is especially useful when you import multiple files that might have overlapping function names.

Growing into a multi-file project

Say you're building a small service. Start with mako init, then add files as you go:

mako init myservice --name myservice
cd myservice
myservice/
  mako.toml
  main.mko
  routes.mko       # you add this
  db.mko           # you add this
// db.mko
fn db_init() {
    print("database ready")
}

fn db_count() -> int {
    return 42
}
// routes.mko
fn routes_health(c: int) {
    let _ = http_respond_json(c, 200, "{\"ok\":true}")
}
// main.mko
import "./routes.mko"
import "./db.mko"

fn main() {
    db_init()
    let fd = http_bind(8080)
    print("listening on :8080")
    // handle requests...
}

Grouped imports

When you have several imports, group them into a single block:

import (
    "./routes.mko"
    "./db.mko"
    "strings"
)

The formatter (mako fmt) will automatically rewrite multiple single import lines into this grouped form.

Standard library imports

Mako ships with a standard library. Import its modules by name (no ./ prefix):

import "strings"
import "net/http"

fn main() {
    print(strings.trim("  hello  "))
}

When to use packages instead

File imports work great within a single project. When you want to share code across projects, or your codebase grows large enough to need separate build units, reach for packages and workspaces -- covered in Chapter 10: Packages.

Editor setup

VS Code

A Mako extension is available that provides:

Install it from the extensions marketplace or point your editor at the .mko grammar file in the repository under editors/vscode/.

Vim / Neovim

Add .mko filetype detection to your configuration:

autocmd BufRead,BufNewFile *.mko set filetype=mako

For LSP integration, configure the Mako language server in your LSP client settings.

General editor tips

Common first-day commands

# Check your installation
mako version
mako doctor

# Create and run a project
mako init hello --name hello
cd hello
mako run main.mko

# Type-check without building
mako check main.mko

# Build a release binary
mako build --release main.mko

# Format your code
mako fmt main.mko

# Run tests
mako test examples/testing

Troubleshooting

"clang: command not found"

Install clang. On macOS: xcode-select --install. On Ubuntu/Debian: sudo apt install clang. On Fedora: sudo dnf install clang.

"runtime headers not found"

Either run make install again or set MAKO_RUNTIME to point at the runtime directory.

"permission denied" on ~/.local/bin/mako

Ensure ~/.local/bin exists and is writable:

mkdir -p ~/.local/bin
make install

Build cache issues

If you suspect stale cache artifacts, clean and rebuild:

mako build --clean main.mko

Next steps

You now have Mako installed, know how to create projects, and can build and run programs. The next chapter is a comprehensive tour of the language syntax.

Next: Language Tour.

Edit this page on GitHub Report an issue