.NET Interop

Jitzu compiles to bytecode and runs on .NET 10. This means you can call any .NET method, access properties, create instances of .NET types, and install NuGet packages — all from Jitzu code.

Built-in .NET Types

These types are available without any imports:

Jitzu name.NET typeExample
IntSystem.Int32Int.Parse("42")
DoubleSystem.DoubleDouble.Parse("3.14")
StringSystem.String"hello".ToUpper()
BoolSystem.Booleantrue
CharSystem.Char'a'
DateSystem.DateOnlyDate.parse("2024-01-01")
TimeSystem.TimeOnlyTime.parse("12:00:00")
DateTimeSystem.DateTimeDateTime.Now
FileSystem.IO.FileFile.Exists("config.json")
PathSystem.IO.PathPath.GetFileName("src/main.jz")

Calling Instance Methods

Call .NET methods on any value using their original PascalCase names:

Jitzu
let msg = "Hello, World!"

// String instance methods
print(msg.ToUpper())          // "HELLO, WORLD!"
print(msg.ToLower())          // "hello, world!"
print(msg.Trim())             // "Hello, World!"
print(msg.Contains("World"))  // true
print(msg.StartsWith("He"))   // true
print(msg.Replace("World", "Jitzu"))  // "Hello, Jitzu!"
print(msg.Substring(0, 5))    // "Hello"
print(msg.Split(","))         // ["Hello", " World!"]
print(msg.IndexOf("World"))   // 7

Accessing Properties

Access .NET properties with dot notation — just like fields:

Jitzu
let msg = "Hello"
print(msg.Length)  // 5

let items = [1, 2, 3]
print(items.Count) // 3

Calling Static Methods

Call static methods on a type name:

Jitzu
// Parsing
let n = try Int.Parse("42")
let pi = try Double.Parse("3.14159")

// File operations
let exists = File.Exists("config.json")
let ext = Path.GetExtension("script.jz")     // ".jz"
let name = Path.GetFileName("src/Parser.cs")  // "Parser.cs"
let dir = Path.GetDirectoryName("/home/user/file.txt")

NuGet Packages

Any public NuGet package works in Jitzu. Add a #:package directive at the top of your script — no project files, no restore step.

Jitzu
#:package Newtonsoft.Json@13.0.4

let user = { name = "Alice", age = 30 }
let json = JsonConvert.SerializeObject(user)
print(json)  // {"name":"Alice","age":30}

Specifying Versions

The version follows the package name after @:

Jitzu
#:package Serilog@4.3.1
#:package Serilog.Sinks.Console@6.1.1

let logger_config = LoggerConfiguration { }
Log.Logger = logger_config.WriteTo.Console().CreateLogger()

Log.Information("Hello from Serilog!")
Log.CloseAndFlush()

Packages are downloaded to ~/.nuget/packages and cached for future runs. Dependencies are resolved automatically.

Creating .NET Instances

Construct .NET types with the object initializer syntax:

Jitzu
#:package Serilog@4.3.1

// Parameterless constructor + property assignment
let config = LoggerConfiguration { }

Method Name Conversion

Jitzu functions use snake_case, but .NET methods use PascalCase. When calling .NET methods, use PascalCase — these are CLR calls, not Jitzu functions:

Jitzu
// ✓ .NET methods — PascalCase (their original names)
let upper = name.ToUpper()
let parts = line.Split(",")
let n = Int.Parse("42")

// ✗ Don't use snake_case for .NET methods
// name.to_upper()   — won't find the method
// Int.parse("42")   — won't find the method

Namespace Resolution

Types from NuGet packages are registered with their full .NET namespace. If a type name is unique across all loaded packages, you can use just the short name:

Jitzu
#:package Newtonsoft.Json@13.0.4

// Short name works when unambiguous
let json = JsonConvert.SerializeObject(data)

If two packages export the same type name, Jitzu tells you:

Jitzu
// Error: Type 'JsonSerializer' is ambiguous. Did you mean:
//   - System.Text.Json.JsonSerializer
//   - Newtonsoft.Json.JsonSerializer

// Fix: use the fully qualified name
let s = System.Text.Json.JsonSerializer {}

Common Errors

Method not found

Jitzu
let name = "Alice"
name.Foo()
// Error: Cannot find function 'Foo' on 'String'

// Fix: check the method name and casing
name.ToUpper()

Wrong argument types

Jitzu
Int.Parse(42)
// Error: Cannot find function 'Parse' on 'Int' with argument types: Int

// Fix: Parse expects a String
Int.Parse("42")

Package not found

If a #:package directive specifies a version that doesn’t exist, the script will fail at startup before any code runs. Double-check the package name and version on nuget.org.

Next, explore the Code Style guide for naming conventions.