This is the guided start: you create a folder, paste two small files, and end up stepping through your first Mica program in a real debugger — variables in the panel, breakpoints on source lines. It takes about fifteen minutes, works the same on macOS and Linux, and installs nothing on your machine beyond Docker and VS Code.

The short way. Everything on this page also exists ready-made: clone the starter repository into ~/source/repos, the folder its container opens on, open it in VS Code, choose Reopen in Container and then Mica Developer, and you have the container, all the example suite, the benchmarks and F5 debugging over every one of them.

mkdir -p ~/source/repos
cd ~/source/repos
git clone https://gitlab.com/mica-dev/mica-container.git
code mica-container

That repository is the starter for Mica and the home of this tutorial series.

This page is the long way, and it is worth the fifteen minutes once: you build the setup by hand, so you know what each piece does rather than inheriting it.

What you need — once

  1. Docker Desktop (macOS) or Docker Engine (Linux), running.
  2. VS Code.
  3. In VS Code, the Dev Containers extension — open the Extensions view, search Dev Containers, install the one by Microsoft (ms-vscode-remote.remote-containers).

That is the only extension you install yourself. The Mica language extension and the debugger extension arrive automatically in a moment — the container configuration you are about to paste names them, and VS Code installs them inside the container for you.

Step 1 — an empty folder

In a terminal:

mkdir hello-mica && cd hello-mica
mkdir .devcontainer
code .

The dot-folder is where VS Code looks for the container description. Nothing else needs configuring: building, running and debugging a Mica file is the Mica extension’s job, with no launch or task file to write.

(If code is not on your PATH: open VS Code, press F1, run Shell Command: Install ‘code’ command in PATH — or simply open the folder via File → Open Folder.)

Step 2 — describe the container

In VS Code’s Explorer, create a file devcontainer.json inside the .devcontainer folder, with exactly this content:

{
  "name": "Mica",
  "image": "micalang/mica:latest",
  "customizations": {
    "vscode": {
      "extensions": [
        "mica-development-ug.mica-language",
        "ms-vscode.cpptools"
      ]
    }
  },
  "runArgs": ["--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined"],
  "containerEnv": { "DEBUGINFOD_URLS": "" },
  "remoteUser": "mica"
}

Four facts in one file: which image to run (the official Mica image — compiler, linker tools, gdb and an editor, for Intel and ARM machines alike), which two extensions to install inside it, and debugger-friendly container settings — including switching off gdb’s online symbol lookup, which would otherwise freeze containerized debug sessions for minutes.

Step 3 — your first program

Create Hello.mica:

program Hello;

imp
    WriteLn : std;

begin
    WriteLn("Hello, Mica!");
end.

Two things worth noticing already. program Hello; names the program — the compiled binary will be named Hello after this declaration, and by convention the file carries the same name. And WriteLn is imported: in Mica everything a program uses arrives through an imp declaration, so a source file tells you its dependencies honestly — nothing is ambient.

Step 4 — reopen in the container

VS Code has noticed the .devcontainer folder and offers Reopen in Container in the corner — click it (or press F1 and run Dev Containers: Reopen in Container).

The first time, this pulls the image and installs the two extensions into it — a minute or two. Every later open is seconds. When the window reloads you are inside the container: the Mica extension is active, and hovering WriteLn shows its signature — that answer comes from the compiler itself, running as a language server.

Step 5 — compile it

Open a terminal (Terminal → New Terminal — it is a shell inside the container) and:

mica-build-debug Hello.mica

Everything the build produces lands in a folder named after the source file: build/Hello/. There is a sibling, mica-build-fullopt, that produces the fully optimized build with the same usage — but for the debugger, the debug tier is the one you want.

Step 6 — run it

./build/Hello/Hello
Hello, Mica!

Two namings meet here: the folder is named after the file, the binary after the program declaration in the source — and by Mica convention the two agree, which is why the file is called Hello.mica. Rename the program, and the binary renames with it: the source is in charge.

Step 7 — something worth debugging

Replace the content of Hello.mica with:

program Hello;

imp
    WriteLn : std;

var
    greeting : string;
    answer : int64;

begin
    greeting := "Hello, Mica!";
    answer := 6 * 7;
    WriteLn("%ls says the answer is %lld", greeting, answer);
end.

var declares variables with explicit types; := assigns. The format string is checked at compile time: %ls is a string, %lld an int64. Try changing %lld to %d and saving — the editor underlines it immediately with the compiler’s own error (format specifier ‘%d’ at position 2 incompatible with type: int64), because the language server runs the same analysis the build does. Change it back.

Step 8 — breakpoint, inspect, step

  1. Make sure Hello.mica is the active editor tab — F5 builds and debugs whatever Mica file you have focused, so debugging always starts from the program you are looking at. Then click in the gutter left of the WriteLn line — a red breakpoint dot appears.
  2. Press F5. The Mica extension builds Hello.mica at the debug tier and starts gdb on it, and the program stops at your breakpoint. (The Debug Console fills with startup chatter — gdb’s version banner, a Failed to set controlling terminal warning. All of it is harmless and none of it is Mica: the stop and the Variables panel are the debugger working.)
  3. Look at the Variables panel: greeting is there with its text and its length of 12 runes, answer is 42, and exit — the program’s result variable — is 0.
  4. Press F10 to step over the WriteLn line. The Debug Console shows Hello, Mica! says the answer is 42.
  5. Press F5 to let the program finish.

The Run and Debug actions above program Hello; do the same as the terminal and F5, and the Launch Card beside them is where a program’s runtime flags and arguments are set when it needs some.

You have compiled, run, and stepped through native ARM64 or x86-64 machine code — whichever your machine speaks — with full source-level debugging, and nothing was installed on your computer beyond Docker and VS Code.

Where to go next

Mica as a scripting language is the five-minute stop worth making before the series proper: one command compiles and runs a file, a shebang line turns it into a tool on your PATH, and every compile-time check runs before the program does. It changes how you use everything that follows.

Part 2: The shape of a Mica program reads that program properly — the four parts every Mica program has, why every name must be imported, and the format string the compiler checks before it builds anything. It works from the starter repository, cloned into ~/source/repos as the short way above shows, which carries you into the rest of the series.

Meanwhile:

Stuck, or delighted? info@mica-dev.com reads everything.