Using Native Packages
Native packages use the same @import(...) syntax as source modules, but the
import resolves package metadata and a compiled shared library rather than a
single .kel source file.
A complete local example
Section titled “A complete local example”The math used below is the reference native package at
packages/examples/math/ in the Kelvra runtime repository. ./build.sh builds it
into the repository’s package output, which is why the bare "math" import can
resolve when running examples from a source checkout.
const math = @import("math")
print(math.addI64(1i64, 2i64))print(math.MEANING_OF_LIFE)print(math.greet("Turing"))package math
@doc("Reference constant export.")const MEANING_OF_LIFE i64
@doc("Add two i64 values.")fn addI64(lhs i64, rhs i64) i64
@doc("Return a greeting for the provided name.")fn greet(name str) strkind = "native"import_name = "math"namespace = "examples"name = "math"version = "0.1.0"abi_version = 3kelvra_runtime = "^0.2.0"package.api.kel is the public Kelvra-facing contract. The corresponding
package.cpp implements and registers those functions and constants through
the native package ABI.
Bare import names such as "math" resolve through package metadata. Canonical
module paths such as "github.com/kelvralang/fs" resolve installed dependencies.
Path-like imports such as "./math.kel" stay source-module imports.
Search paths
Section titled “Search paths”The current interpreter searches for packages in:
build/packagesrelative to the interpreter binary- any roots passed with
--package-path packages/relative to the importing source file or current working directory
You can add extra roots explicitly:
kelvra run --package-path /path/to/packages app.kelOpaque package types
Section titled “Opaque package types”Packages can expose opaque handle types through package.api.kel.
const counter = @import("counter")
const first counter.Counter = counter.create(10i64)const second counter.Counter = counter.create(20i64)
print(counter.read(first))print(counter.add(second, 5i64))Those values are package-managed handles, but the type checker still tracks their package identity.
API declaration files
Section titled “API declaration files”Native packages can ship package.api.kel for:
- readable public signatures
- editor navigation and hover docs
- public opaque type declarations
The reference packages under packages/examples/ are the best examples in this
repo.
Installing published native packages
Section titled “Installing published native packages”Published native packages use the same dependency workflow as source packages, but installs may need to choose between a prebuilt artifact and a local source build.
Useful flags:
kelvra install --target <triple>to select a specific native targetkelvra install --prefer-prebuiltto stay on registry-published binaries when availablekelvra install --no-native-buildto reject source fallbackkelvra install --cmake-toolchain <path>to allow non-host source-build fallback
When a registry entry only publishes source for the requested target, Kelvra
records build_from_source = true and the selected target in kelvra.lock.
Subsequent kelvra run --locked --target <triple> executions can reuse the cached
install without rebuilding.
Validating a package
Section titled “Validating a package”Validate a package directory against its manifest and compiled shared library:
kelvra validate-package packages/examples/mathkelvra validate-package packages/examples/counterThe current validator checks package ID syntax, reserved kelvra usage,
manifest/ABI compatibility, registration metadata, and exported native
signature parsing.