Odin Development Guide
Treat the active compiler distribution as the primary source of truth. Odin is still evolving, so remembered syntax and online examples from another release may be wrong for the user's compiler.
Start with the project
- Read the README, build scripts, CI, and nearby
.odin files before choosing commands or layout.
- Honor any project-pinned compiler/version instead of silently using another installation.
- Locate the package directory. Odin commands normally take a directory; eligible
.odin files there form one package and declare the same package name.
- Capture the active environment without scanning the filesystem:
odin version
odin root
odin help <command>
odin root resolves matching base, core, vendor, and examples when included, without platform-specific paths. If odin is missing, use the official installation guide rather than guessing package-manager or linker setup.
Minimal executable smoke test:
package main
import "core:fmt"
main :: proc() {
fmt.println("Hello, Odin!")
}
Command map
Prefer the project's established command. Otherwise use the narrowest applicable command:
odin check <package-dir> -vet # executable package
odin check <library-dir> -no-entry-point -vet # package without main
odin build <package-dir>
odin build <package-dir> -debug # debug info + ODIN_DEBUG
odin run <package-dir>
odin run <package-dir> -- <program-args>
odin test <package-dir> -vet # @(test) procedures
odin check path/to/file.odin -file -vet # self-contained file only
odin doc core:fmt -short # installed package API
-file is for a self-contained file, not a package directory.
-vet is useful for first-party code; preserve intentional project policy and do not impose it on unrelated third-party code.
- Confirm uncommon or release-sensitive flags with
odin help build, check, test, or doc.
- Custom collections use
-collection:<name>=<directory> and imports such as import "<name>:pkg". Current compilers can also resolve collection-qualified native library paths in foreign import; confirm this in odin help check for older project toolchains and reuse the project's convention.
Find exact APIs before coding
Resolve <odin-root> with odin root, then use these version-matched locations:
| Need |
Path |
| Language feature survey |
<odin-root>/examples/demo/demo.odin |
| Bundled-example index |
<odin-root>/examples/README.md |
core:x/y implementation |
<odin-root>/core/x/y/ |
vendor:x/y binding |
<odin-root>/vendor/x/y/ |
| Installed vendor index |
<odin-root>/vendor/README.md |
| Runtime and intrinsics |
<odin-root>/base/ |
Use odin doc <collection:package> -short for discovery, then read that package's source, comments, tests, README, and adjacent examples. For foreign bindings, prefer the installed Odin declarations over upstream C examples: names, types, libraries, feature flags, and ownership may differ.
Official references:
Online pages may track a newer revision. If sources disagree, prefer project constraints, compiler diagnostics, local source, and a matching release/tag over master.
Core language patterns
Read the core language patterns before implementing anything beyond a minimal entry point, diagnosing type/ownership behavior, reviewing unfamiliar syntax, or teaching Odin. It gives compiler-checked examples for declarations, procedures, control flow, types, containers, allocation, optional/error handling, parametric polymorphism, strings/FFI, and tests. For a narrow task, read the relevant headings rather than treating it as a fixed specification.
The official Odin Overview is the broader language reference and covers many features intentionally omitted here. Consult its relevant section whenever syntax or semantics are unfamiliar or release-sensitive. If documentation and memory are still insufficient, create the smallest disposable package under the system temporary directory and compile it with the project's exact compiler and flags:
odin check <system-temp>/odin-probe -vet
odin test <system-temp>/odin-probe -vet # assertions or library behavior
odin run <system-temp>/odin-probe # only when runtime behavior matters
Keep probes outside the user's project, reproduce only the uncertain feature, and remove them afterwards. Compiler diagnostics beat speculation.
Keep these high-level guardrails in mind:
:= declares an inferred mutable variable; :: declares a compile-time entity such as a constant, type, or procedure. Numeric conversions are generally explicit.
when is compile-time control flow; if is runtime. defer runs when its current lexical scope exits, so scope affects cleanup and paired operations.
- Fixed arrays, slices, dynamic arrays, and maps differ in value semantics, backing storage, and allocation. Identify the owner and lifetime.
- For allocations and resources, use the appropriate
delete, free, package cleanup, or allocator teardown. Place cleanup with defer after successful acquisition and check implicit context.allocator use.
- Follow each package's actual multi-result,
ok, error, or union convention; do not invent exceptions or assume a universal error type.
string and cstring differ. At FFI boundaries, verify termination, conversion, mutability, and lifetime in the binding source.
- Check current syntax and nearby idioms before using
$ parameters or other parametric features.
Edit and verify
- Follow the target package's naming, organization, allocator, and error style; avoid unrelated rewrites.
- Compile a minimal reproduction with the same compiler whenever an API or syntax point is uncertain.
- After each logical edit, run
odin check on the narrowest affected package, then relevant tests. Build or run when linking or runtime behavior matters.
- Preserve platform suffixes, build tags, foreign-library setup, and project flags.
- For toolchain failures, collect
odin version, odin report, the exact command, and the first diagnostic before changing dependencies.
- Report commands that passed and checks that could not run.
Do not freeze a framework or package catalog into this skill. Discover the installed collections and current official examples at task time so the guidance remains small and revision-compatible.
1---2name: odin-lang3description: Version-aware guidance for practical Odin development. Use whenever a task mentions Odin, .odin files, Odin packages or import collections, odin build/run/check/test/doc, compiler or linker errors, core: or vendor: APIs, FFI, Odin language features, or project setup—even when Odin is only part of a larger task. Locates the active toolchain and matching docs/examples, explains core syntax and semantics with compiler-checked examples, guides idiomatic edits, and verifies changes without assuming an OS, editor, framework, or application domain.4license: MIT5---67# Odin Development Guide89Treat the active compiler distribution as the primary source of truth. Odin is still evolving, so remembered syntax and online examples from another release may be wrong for the user's compiler.1011## Start with the project12131. Read the README, build scripts, CI, and nearby `.odin` files before choosing commands or layout.142. Honor any project-pinned compiler/version instead of silently using another installation.153. Locate the package directory. Odin commands normally take a directory; eligible `.odin` files there form one package and declare the same package name.164. Capture the active environment without scanning the filesystem:1718```text19odin version20odin root21odin help <command>22```2324`odin root` resolves matching `base`, `core`, `vendor`, and examples when included, without platform-specific paths. If `odin` is missing, use the official installation guide rather than guessing package-manager or linker setup.2526Minimal executable smoke test:2728```odin29package main3031import "core:fmt"3233main :: proc() {34 fmt.println("Hello, Odin!")35}36```3738## Command map3940Prefer the project's established command. Otherwise use the narrowest applicable command:4142```text43odin check <package-dir> -vet # executable package44odin check <library-dir> -no-entry-point -vet # package without main45odin build <package-dir>46odin build <package-dir> -debug # debug info + ODIN_DEBUG47odin run <package-dir>48odin run <package-dir> -- <program-args>49odin test <package-dir> -vet # @(test) procedures50odin check path/to/file.odin -file -vet # self-contained file only51odin doc core:fmt -short # installed package API52```5354- `-file` is for a self-contained file, not a package directory.55- `-vet` is useful for first-party code; preserve intentional project policy and do not impose it on unrelated third-party code.56- Confirm uncommon or release-sensitive flags with `odin help build`, `check`, `test`, or `doc`.57- Custom collections use `-collection:<name>=<directory>` and imports such as `import "<name>:pkg"`. Current compilers can also resolve collection-qualified native library paths in `foreign import`; confirm this in `odin help check` for older project toolchains and reuse the project's convention.5859## Find exact APIs before coding6061Resolve `<odin-root>` with `odin root`, then use these version-matched locations:6263| Need | Path |64|---|---|65| Language feature survey | `<odin-root>/examples/demo/demo.odin` |66| Bundled-example index | `<odin-root>/examples/README.md` |67| `core:x/y` implementation | `<odin-root>/core/x/y/` |68| `vendor:x/y` binding | `<odin-root>/vendor/x/y/` |69| Installed vendor index | `<odin-root>/vendor/README.md` |70| Runtime and intrinsics | `<odin-root>/base/` |7172Use `odin doc <collection:package> -short` for discovery, then read that package's source, comments, tests, README, and adjacent examples. For foreign bindings, prefer the installed Odin declarations over upstream C examples: names, types, libraries, feature flags, and ownership may differ.7374Official references:7576- Docs index: https://odin-lang.org/docs/77- Install: https://odin-lang.org/docs/install/78- Language overview: https://odin-lang.org/docs/overview/79- Annotated demo: https://odin-lang.org/docs/demo/80- Testing: https://odin-lang.org/docs/testing/81- FAQ: https://odin-lang.org/docs/faq/82- `core`/`vendor` APIs: https://pkg.odin-lang.org/83- Idiomatic examples: https://github.com/odin-lang/examples84- Compiler, collections, grammar, and tests: https://github.com/odin-lang/Odin8586Online pages may track a newer revision. If sources disagree, prefer project constraints, compiler diagnostics, local source, and a matching release/tag over `master`.8788## Core language patterns8990Read [the core language patterns](references/language-basics.md) before implementing anything beyond a minimal entry point, diagnosing type/ownership behavior, reviewing unfamiliar syntax, or teaching Odin. It gives compiler-checked examples for declarations, procedures, control flow, types, containers, allocation, optional/error handling, parametric polymorphism, strings/FFI, and tests. For a narrow task, read the relevant headings rather than treating it as a fixed specification.9192The official [Odin Overview](https://odin-lang.org/docs/overview/) is the broader language reference and covers many features intentionally omitted here. Consult its relevant section whenever syntax or semantics are unfamiliar or release-sensitive. If documentation and memory are still insufficient, create the smallest disposable package under the system temporary directory and compile it with the project's exact compiler and flags:9394```text95odin check <system-temp>/odin-probe -vet96odin test <system-temp>/odin-probe -vet # assertions or library behavior97odin run <system-temp>/odin-probe # only when runtime behavior matters98```99100Keep probes outside the user's project, reproduce only the uncertain feature, and remove them afterwards. Compiler diagnostics beat speculation.101102Keep these high-level guardrails in mind:103104- `:=` declares an inferred mutable variable; `::` declares a compile-time entity such as a constant, type, or procedure. Numeric conversions are generally explicit.105- `when` is compile-time control flow; `if` is runtime. `defer` runs when its current lexical scope exits, so scope affects cleanup and paired operations.106- Fixed arrays, slices, dynamic arrays, and maps differ in value semantics, backing storage, and allocation. Identify the owner and lifetime.107- For allocations and resources, use the appropriate `delete`, `free`, package cleanup, or allocator teardown. Place cleanup with `defer` after successful acquisition and check implicit `context.allocator` use.108- Follow each package's actual multi-result, `ok`, error, or union convention; do not invent exceptions or assume a universal error type.109- `string` and `cstring` differ. At FFI boundaries, verify termination, conversion, mutability, and lifetime in the binding source.110- Check current syntax and nearby idioms before using `$` parameters or other parametric features.111112## Edit and verify1131141. Follow the target package's naming, organization, allocator, and error style; avoid unrelated rewrites.1152. Compile a minimal reproduction with the same compiler whenever an API or syntax point is uncertain.1163. After each logical edit, run `odin check` on the narrowest affected package, then relevant tests. Build or run when linking or runtime behavior matters.1174. Preserve platform suffixes, build tags, foreign-library setup, and project flags.1185. For toolchain failures, collect `odin version`, `odin report`, the exact command, and the first diagnostic before changing dependencies.1196. Report commands that passed and checks that could not run.120121Do not freeze a framework or package catalog into this skill. Discover the installed collections and current official examples at task time so the guidance remains small and revision-compatible.