scripting.md

CLI Scripting with Roc

Scripts run with roc or compile to standalone binaries via the basic-cli platform.

Platform version: Examples use basic-cli 0.20.0. Check https://github.com/roc-lang/basic-cli/releases for latest.

Script structure

#!/usr/bin/env roc
app [main!] { cli: platform "https://github.com/roc-lang/basic-cli/releases/download/0.20.0/X73hGh05nNTkDHU06FHC0YfFaQB1pimX7gncRcao5mU.tar.br" }

import cli.Stdout

main! = |_args|
    Stdout.line!("Hello, World!")

Make executable: chmod +x script.roc, then run: ./script.roc

If roc not in PATH, use full path in shebang: #!/home/user/.local/share/roc/current/roc

Command-line arguments

#!/usr/bin/env roc
app [main!] {
    cli: platform "https://github.com/roc-lang/basic-cli/releases/download/0.20.0/X73hGh05nNTkDHU06FHC0YfFaQB1pimX7gncRcao5mU.tar.br",
}

import cli.Stdout
import cli.Arg exposing [Arg]

main! : List Arg => Result {} _
main! = |raw_args|
    args = List.map(raw_args, Arg.display)

    # Index 0 is executable path, 1 is first real argument
    when List.get(args, 1) is
        Err(_) ->
            Err(Exit(1, "Error: Expected one argument\n\tUsage: ./script.roc <input>"))

        Ok(first_arg) ->
            Stdout.line!("Received: ${first_arg}")

Platform imports

Common modules from cli platform:

Module Purpose
cli.Stdout Write to stdout
cli.Stdin Read from stdin
cli.File File operations
cli.Path Path handling
cli.Arg Command-line arguments
cli.Env Environment variables
cli.Dir Directory operations

Reading stdin

import cli.Stdin
import cli.Stdout

main! = |_args|
    input = Stdin.line!
    Stdout.line!("You entered: ${input}")

File operations

import cli.File
import cli.Path
import cli.Stdout

main! = |_args|
    path = Path.from_str("input.txt")
    content = File.read_utf8!(path)?
    Stdout.line!("File content: ${content}")

When to use Roc scripts

Good for:

  • Type-safe scripts catching errors at compile time
  • Functional programming enthusiasts
  • Long-lived scripts benefiting from stability
  • Learning functional programming

Avoid for:

  • Production-critical code (Roc pre-1.0, breaking changes possible)
  • Quick throwaway scripts (compilation overhead)
  • When team doesn't know functional programming