Skip to content

Modules

Understand how Atoll groups source files into project namespaces.

Updated View as Markdown

A module is a directory of Atoll source files. The project compiler derives a file’s module path from the project root, its atoll.toml module name, and the file’s parent directory.

seaport/
  atoll.toml
  main.at
  core/
    models/
      booking.at
      customer.at

With module = "workreef.dev/seaport", these files belong to:

File Module
main.at workreef.dev/seaport
core/models/booking.at workreef.dev/seaport/core/models
core/models/customer.at workreef.dev/seaport/core/models

The filename is not part of the module path.

Renaming booking.at therefore does not change its declarations’ import path as long as it stays in the same directory. Moving it to another directory does.

Shared scope

Files in one directory share a module namespace. Public declarations from one file are available to another file in that directory without an import.

// booking.at
struct Booking {
    id: int
}
// display.at
fn booking_label(booking: Booking): string {
    return "booking ${booking.id}"
}

A module is therefore larger than a file but smaller than a project. Duplicate top-level names across sibling files conflict just as they would in one file.

Project checking registers declarations across the whole source set before resolving bodies. Forward references and mutual imports between modules can therefore resolve, including multi-module cycles. This does not make recursive value layouts valid; it only means import order is not a source-order restriction.

workreef.dev/seaport/orders  -> workreef.dev/seaport/customers
workreef.dev/seaport/customers -> workreef.dev/seaport/orders

Keep dependency cycles small even though they are supported. A lower-level shared module often communicates the design more clearly than two feature modules that import each other broadly.

Source headers

Do not add a module declaration to ordinary source files. The parser still accepts the legacy header for compatibility, but the current project pipeline uses filesystem and manifest metadata as the source of truth.

The loader and editor derive the same path from the parent directory. A source header cannot override that derived identity.

Cross-module access

Code in another directory needs an import. Exported declarations are public by default; visibility can restrict them to their declaring file.

Imports are file-local. Same-directory public names are the only declarations made available automatically across source files.

Project roots

The normal project root is the directory containing atoll.toml. atoll check can also inspect a directory without a manifest as an ad-hoc project. In that mode the directory name becomes a synthetic root module, and dependency, datasource, and host-capability configuration is unavailable.

Discovery

The project loader recursively reads .at files. It skips:

  • dot-prefixed directories;
  • target;
  • node_modules;
  • build.

Directory entries are sorted before loading so diagnostics and project input remain deterministic. Files with other extensions do not participate in module scope.

Extra roots and dependencies can contribute more modules. A dependency carrying its own atoll.toml keeps its declared module root; a bare local dependency uses the dependency key as its root.

Organization

The compiler does not require one declaration per file. That remains a useful human convention for primary public types, while closely related private helpers can stay beside their caller. Directory names should express stable domain or layer boundaries because they become public import paths.

Read Projects for manifest and dependency behavior.

Navigation

Type to search…

↑↓ navigate↵ selectEsc close