Skip to main content
A package is the fundamental unit of code organisation in Kairo. Every Kairo project is a package — it has a name, a version, a declared language version, and a kind that determines how it can be used. Packages own their source files, tests, resources, and documentation under a single root directory, and they declare everything Forge needs to build and publish them through a manifest file called kairo.toml.

Application vs Library packages

Every package declares a kind in its manifest. There are two kinds:

application

A runnable program. Applications declare an entrypoint that Pulse invokes at startup. An application package cannot be listed as a dependency of another package — it is a terminal node in the build graph.

library

A reusable unit of code. Libraries expose a public API and can be declared as dependencies by other packages — both other libraries and applications. Only libraries may appear in a [dependencies] section.
Only library packages can be used as dependencies. If you attempt to add an application package as a dependency, Forge will report an error at restore time.

Standard project layout

Every Kairo package follows the same top-level directory structure. Forge and Studio both expect this layout, so keeping to it avoids configuration overhead and ensures tooling works correctly out of the box.
Here is what each entry is for:
Never place hand-authored or generated source files inside build/ or .forge/. Forge owns those directories entirely and may delete or overwrite their contents at any time. Run forge clean to remove them safely.

Module-to-file mapping

Kairo uses module declarations as the authoritative source of identity — not the filesystem path. A module’s fully qualified name (e.g., Astra.Customers.Orders) is what the compiler and other packages use to refer to it. The file path is a hint, not a contract. That said, you should keep your filesystem layout aligned with your module names. The conventional mapping is:
  • Use lowercase kebab-case for file names (e.g., customer-service.ak, order-line.ak).
  • Place one module declaration per file.
  • A single module may span multiple files, as long as all those files live in the same directory.
  • Transitive dependencies are not implicit source imports — you must explicitly import every module your code depends on, even if it comes from a package you depend on indirectly.
Keeping file names and directory structure closely aligned with module names makes navigation predictable and helps Studio’s project view stay organised.

Next steps

Manifest

Learn every field in kairo.toml — package identity, versioning, entrypoints, and runtime configuration.

Dependencies

Declare and lock your dependencies with [dependencies] and forge.lock.