Table of Contents

The Package Manager

Why a package manager?

As projects grow, you need a way to organize code into modules, share libraries, and ensure reproducible builds. Nyx ships with a built-in package manager that handles all of this through a single configuration file: nyx.toml.

No external tools required. No npm, no pip, no cargo to install separately. It is part of the compiler.

The nyx.toml format

Every Nyx project has a nyx.toml file at its root. It describes the project and its dependencies:

# nyx.toml

[package]
name = "myapp"
version = "0.1.0"
main = "src/main.nx"
description = "A web API for managing tasks"

[dependencies]
json = "*"
http = "https://github.com/nyxlang-dev/http"

The [package] section describes your project:

KeyRequiredDescription
nameYesProject name (used for the output binary)
versionYesSemantic version (e.g. "0.1.0")
mainNoEntry point file (default: src/main.nx)
descriptionNoShort project description
no_gcNoSet to true for systems mode without garbage collector

The [dependencies] section lists libraries your project depends on. Each dependency is fetched via git clone into a packages/ directory.

Creating a project with nyx init

The fastest way to start a new project:

$ mkdir my-api
$ cd my-api
$ nyx init

This creates two files:

my-api/
  nyx.toml       ← project configuration
  src/
    main.nx      ← entry point

The generated nyx.toml uses the directory name as the project name, and src/main.nx contains a hello-world program.

Building and running

nyx build reads nyx.toml, resolves any dependencies, compiles the project, and produces a native binary:

$ nyx build
Resolving dependencies...
Compiling my-api v0.1.0
  Built: my-api

For optimized builds, add the --release flag:

$ nyx build --release

To build and run in one step:

$ nyx run

After a successful build, a nyx.lock file is written to record the exact versions of all dependencies. Commit this file to version control for reproducible builds.

Adding dependencies

The nyx add command adds a package from the default registry:

$ nyx add json

This clones the package into packages/json/ and adds it to nyx.toml. To add from a custom URL:

$ nyx add mylib --from https://github.com/user/mylib

Importing from packages

After adding a package, import its modules using the package name as prefix:

// After: nyx add nyx-db
import "nyx-db/src/query"

fn main() {
    db_query("CREATE TABLE users (id INT PRIMARY KEY, name TEXT)")
    db_query("INSERT INTO users VALUES (1, 'Alice')")
    let rows: Array = db_query_rows("SELECT * FROM users")
}

The compiler resolves import "nyx-db/src/query" to packages/nyx-db/src/query.nx. Internal imports within the package (like import "src/store") are automatically rewritten so transitive dependencies resolve correctly.

Inspecting a project

The nyx info command prints project metadata:

$ nyx info
  name: my-api
  version: 0.1.0
  main: src/main.nx
  description: A web API for managing tasks
  gc: enabled

Practical example

Let's build a small project from scratch:

$ mkdir greeter && cd greeter
$ nyx init

Edit src/main.nx:

fn greet(name: String) -> String {
    return "Hello, " + name + "!"
}

fn main() {
    let args: Array = get_args()
    if args.length() > 1 {
        let name: String = args[1]
        println(greet(name))
    } else {
        println(greet("World"))
    }
}

Build and run:

$ nyx run
Hello, World!

$ nyx build
$ ./greeter Alice
Hello, Alice!

Summary

← Previous: Case study — How nyx-kv was built Next: Building web APIs with nyx-serve →