Skip to content

:core — The Monastery

“No magic. No surprises. Just code.”

:core is the foundation of Janus. Every other profile extends :core — nothing is removed, only added. If you want to understand how Janus really works, start here. If you want to build something that just works, start here too.


  • 6 core types: i64, f64, bool, String, Array[T], HashMap[K, V]
  • 8 control constructs: func, let, var, if, else, for, while, return
  • No hidden state: Every allocation is explicit
  • No implicit concurrency: What you write is what runs
  • Native Janus stdlib first: prefer use std.*; reserve use zig for explicit bridge modules or generated wrappers
  • Structural typing with inference
  • Generic functions with constraints
  • Pattern matching on enums and structs
  • No null — use Option[T] instead
  • You choose the allocator (Arena, Pool, Bump, or custom)
  • No garbage collection — ever
  • Deterministic destruction via defer and explicit cleanup
  • Memory ownership is always visible in your code

ExcludedAvailable In
spawn, send, receive:cluster
async/await:service, :cluster
Tensors and GPU code:compute
Raw pointers and unsafe:sovereign
Effects system:sovereign

Perfect for:

  • CLI tools and automation
  • Embedded systems (ESP32, Raspberry Pi Pico)
  • Learning Janus from first principles
  • Any project where predictability matters more than convenience
  • Libraries that will be used by other profiles
  • Systems programming without the unsafe parts

The rule of thumb: If :core can do what you need, stay in :core. The Monastery is a perfectly valid place to live.


func main() do
print("Hello, Sovereignty!")
end
func fib(n: i64) -> i64 do
if n < 2 do
return n
end
return fib(n - 1) + fib(n - 2)
end
func main() do
for i in 0..10 do
print("fib(${i}) = ${fib(i)}")
end
end
func main() do
let scores = [
{"alice", 95},
{"bob", 87},
{"carol", 92},
]
for pair in scores do
let name = pair.0
let score = pair.1
if score > 90 do
print("${name} earned an A!")
end
end
end
func divide(a: i64, b: i64) -> Option[i64] do
if b == 0 do
return .none
end
return .some(a / b)
end
func main() do
match divide(10, 2) do
| .some(result) => print("10 / 2 = ${result}")
| .none => print("Division by zero!")
end
end

What you write is what you get. There’s no runtime magic. No hidden allocations. No surprising behavior. When something goes wrong, the bug is in your code — not in some abstraction layer you don’t understand.

This is :core. This is Janus.



One language. The foundation is always there.