Starters define code that runs automatically when a program starts.

A starter is function-like, but it is not a normal callable function. It has a body, can use the same statements as a function body, and follows the same lexical scope rules. It does not have a name, parameters, or a return type.

start
(
	console.log("Starting")
)

Typical uses starters instead of requiring a special main() function.

No Parameters

Starters cannot take parameters.

Command-line arguments are accessed through the runtime API instead of being passed into the starter.

start (
	console.log(process.argv)
)

This is invalid:

start(args is string[]) (
)

No Return Type

Starters do not declare a return type.

start (
	setup()
)

Any value produced inside a starter body is ignored unless the program uses it explicitly.

This is invalid:

start is int (
	return 1
)

Not Callable

A starter is called by the program runtime. User code cannot call it directly.

This is invalid:

start()

If code needs to be shared between a starter and another part of the program, put that code in a normal function and call the function from both places.

fn setupLogging() (
)

start (
	setupLogging()
)

Placement

Starters can appear at the top level or inside spaces.

start (
	loadConfig()
)

space server (
	start (
		listen()
	)
)

Starters cannot appear inside classes.

This is invalid:

Server (
	start (
	)
)

Multiple Starters

A program can contain more than one starter.

start (
	configureLogging()
)

start (
	connectDatabase()
)

Starters run in program order after imported wrapper startup has completed. Nested spaces are visited in depth-first order.

This lets setup code live beside the module or space that owns it.

Wrapper Startup

Imported wrapper packages may provide generated startup functions. These functions are distinct from project starters: they are wrapper metadata used to make an imported module ready before its API is used.

Every valid imported wrapper participates in startup, including wrappers imported inside unused spaces and wrappers imported by test targets. Each package version starts at most once.

Wrapper startup functions must be synchronous. They cannot use await, return bombs, or require caller-managed failure handling. A module requiring asynchronous or fallible initialization must expose an ordinary function that project starter code calls explicitly.

Startup functions should be independent. If static analysis finds that one startup function accesses another imported module, the compiler records that dependency and topologically orders the generated calls. Independent functions have no semantic order. A dependency cycle produces notices and short-circuits every startup function in the cycle through unknowable recovery.

The compiler injects the generated wrapper startup dispatcher into Rust main. It completes before ordinary project starters run.

If a wrapper startup function attempts to return a bomb, the compiler produces a notice. If a bomb occurs at runtime, execution of that startup function stops.

Tests

Starters are not called when the entry point is a test.

Tests should set up the state they need directly. Program startup code should not be required just to make a test runnable.

Imported wrapper startup functions still run for tests. They are part of making imported modules valid, not application-specific project startup.