Nori Package Manager¶
Nori is the package manager for Sushi Lang. It handles packaging, installing, and managing precompiled Sushi libraries and executables. Nori ships alongside the compiler in the same distribution.
Table of Contents¶
- Overview
- Getting Started
- The Manifest
- Building Packages
- Installing Packages
- Project Environments
- Searching for Packages
- Managing Packages
- Compiler Integration
- Package Directory Structure
- Archive Format
- Workflow Example
- Command Reference
- Limitations
Overview¶
Nori fills the gap between compiling Sushi libraries and distributing them. The compiler produces .slib files, but getting third-party libraries into the right directories is entirely manual without a package manager.
Nori provides:
- Packaging: Bundle
.sliblibraries, executables, and data files into a distributable.noriarchive - Installation: Extract and install packages to
~/.sushi/bento/ - Discovery: The compiler automatically finds libraries installed by Nori
- Management: List, inspect, and remove installed packages
Important: Nori does not compile Sushi source code. Compile with sushic first, then use Nori to package and distribute the outputs.
Getting Started¶
Nori is included with the Sushi Lang installation. Verify it works:
nori --version
For development from the repository:
./nori --version
The Manifest¶
Every Nori package requires a nori.toml manifest file describing the package and its contents.
Creating a Manifest¶
Generate a template manifest in the current directory:
nori init
This creates a nori.toml with the package name derived from the directory name.
Manifest Format¶
[package]
name = "my-package"
version = "1.0.0"
description = "A useful Sushi package"
author = "Author Name"
license = "Apache-2.0"
[files]
libraries = ["build/mylib.slib"] # .slib files
executables = ["build/mytool"] # compiled binaries
data = ["data/config.toml"] # any other files
[dependencies]
math-utils = "1.0.0"
text-tools = "0.2.1"
The [dependencies] section tracks project-local package versions. Nori populates it automatically when you install packages inside a project directory.
Package Section¶
| Field | Required | Description |
|---|---|---|
name |
Yes | Package name (see naming rules) |
version |
Yes | Semantic version (1.0.0) |
description |
No | Short package description |
author |
No | Author name |
license |
No | License identifier |
Files Section¶
| Field | Description |
|---|---|
libraries |
Paths to .slib files to include |
executables |
Paths to compiled binaries (permissions preserved) |
data |
Paths to data files or directories |
All paths are relative to the directory containing nori.toml.
Naming Rules¶
Package names must: - Start with a lowercase letter - Contain only lowercase letters, digits, and hyphens - Be between 1 and 64 characters
my-package # valid
sushi-utils # valid
MyPackage # invalid (uppercase)
123-lib # invalid (starts with digit)
Version Format¶
Versions must follow major.minor.patch format:
1.0.0 # valid
0.1.0 # valid
2.10.3 # valid
1.0 # invalid (missing patch)
Building Packages¶
Once you have a nori.toml and the referenced files exist, build a package archive:
nori build
This creates a .nori archive in the dist/ directory:
Built my-package v1.0.0
3 file(s), 12.4 KB
dist/my-package-1.0.0.nori
The build command validates that all files listed in the manifest exist before creating the archive.
Installing Packages¶
From a .nori Archive¶
Install directly from an archive file:
nori install ./dist/my-package-1.0.0.nori
From a Directory Containing Archives¶
Use the from syntax to search a directory for a matching archive:
nori install my-package from ./dist/
This finds the archive matching the package name in the specified directory. If multiple versions exist, the latest (by name sort) is used.
From a Source Directory¶
If the source directory contains a nori.toml instead of archives, Nori installs directly from the source:
nori install my-package from ./my-package-src/
What Happens During Installation¶
In a project directory (containing nori.toml):
- The archive is cached in
~/.sushi/cache/ - Contents are extracted to
~/.sushi/store/{name}-{version}/ - A symlink is created at
.sushi_bento/{name}-{version}/in the project root nori.toml[dependencies]is updated with the package version- Executables are symlinked to
~/.sushi/bin/
Outside a project (or with --global):
- The archive is cached in
~/.sushi/cache/ - Contents are extracted to
~/.sushi/bento/{package-name}/ - Executables are symlinked to
~/.sushi/bin/ - A PATH hint is printed for executable access
Re-installing a package replaces the existing installation.
Remote Sources¶
Remote package installation (HTTP URLs, Omakase repository) is planned for a future release.
Project Environments¶
Nori supports project-local dependency management modeled after Go modules and Cargo. When you run nori install inside a directory containing a nori.toml, Nori treats it as a project context and installs packages locally rather than globally.
How It Works¶
Packages have two storage locations:
- Global store:
~/.sushi/store/{name}-{version}/— versioned, immutable copies shared across all projects - Project-local:
.sushi_bento/— symlinks from the project root into the global store
When you install a package inside a project:
- The package is extracted to
~/.sushi/store/{name}-{version}/ - A symlink is created at
.sushi_bento/{name}-{version}/ - The
[dependencies]section ofnori.tomlis updated with the package version
Project Detection¶
Nori detects project context by walking up from the current directory looking for a nori.toml. If found, you are in a project context and installs are project-local by default.
Installing Packages in a Project¶
# Inside a project (nori.toml exists here or in a parent directory)
nori install math-utils-1.0.0.nori # installs to store + symlinks .sushi_bento/
nori install math-utils from ./dist/ # same behavior from a directory source
Restoring All Dependencies¶
To install all packages listed in [dependencies] (e.g., after cloning a project):
nori install
This reads every entry from [dependencies] in nori.toml and installs any that are not already present in the store.
Forcing a Global Install¶
To install globally even when inside a project:
nori install --global math-utils-1.0.0.nori
This installs to ~/.sushi/bento/ and does not update nori.toml.
Committing .sushi_bento/¶
.sushi_bento/ contains only symlinks and is safe to add to .gitignore. The nori.toml [dependencies] section is what should be committed — teammates restore the environment with nori install.
Searching for Packages¶
Search for packages in the Omakase remote repository:
nori search <query>
Example:
nori search math
Output:
Name Version Description
------------------------------ ------------ ------------------------------
math-utils 1.0.0 Math utility library for Sushi
fast-math 0.3.0 SIMD-accelerated math routines
2 result(s) found.
The search queries the Omakase API and returns matching packages by name and description. Results are sorted by relevance. Use pagination flags for large result sets:
nori search math --page 2
nori search math --limit 20
Managing Packages¶
Listing Installed Packages¶
nori list # project-local packages (if in a project), else global
nori list --global # globally installed packages in ~/.sushi/bento/
Output:
Package Version Description
------------------------------ ------------ ------------------------------
math-utils 1.0.0 Math utility library
text-tools 0.2.1 Text processing tools
2 package(s) installed.
Viewing Package Details¶
nori info math-utils
Output:
Package: math-utils
Version: 1.0.0
Description: Math utility library
Author: Jane Doe
License: Apache-2.0
Location: /home/user/.sushi/bento/math-utils
Files:
lib/mathutils.slib
bin/mathcalc
data/constants.toml
Removing Packages¶
nori remove math-utils # removes from project (.sushi_bento/) and updates nori.toml
nori remove --global math-utils # removes from ~/.sushi/bento/
Project removal removes:
- The symlink from .sushi_bento/
- The entry from nori.toml [dependencies]
Global removal removes:
- The package directory from ~/.sushi/bento/
- Executable symlinks from ~/.sushi/bin/
- Cached archives from ~/.sushi/cache/
Compiler Integration¶
Libraries installed by Nori are automatically found by the compiler. No manual SUSHI_LIB_PATH configuration is needed.
Search Order¶
The compiler searches for .slib files in this order:
- Directories in
SUSHI_LIB_PATH(if set) - Project-local packages (
.sushi_bento/*/lib/) - Global Nori packages (
~/.sushi/bento/*/lib/) - Current working directory
Example¶
After installing a package containing mathutils.slib:
# No SUSHI_LIB_PATH needed - the compiler finds it automatically
use <lib/mathutils>
fn main() i32:
let i32 result = add(10, 20).realise(0)
println("{result}")
return Result.Ok(0)
Package Directory Structure¶
Nori uses two storage locations: a global store under ~/.sushi/ and a project-local .sushi_bento/ directory.
Global store¶
~/.sushi/
bin/ # executable symlinks
mytool -> ../store/my-package-1.0.0/bin/mytool
cache/ # downloaded .nori archives
my-package-1.0.0.nori
store/
my-package-1.0.0/ # versioned package copy
nori.toml
lib/
mylib.slib
bin/
mytool
data/
config.toml
bento/
my-package/ # global installs (no project context)
nori.toml
lib/
mylib.slib
Project-local¶
my-project/
nori.toml # manifest with [dependencies]
.sushi_bento/
my-package-1.0.0 -> ~/.sushi/store/my-package-1.0.0/
| Location | Purpose |
|---|---|
~/.sushi/store/ |
Versioned, immutable package copies shared across projects |
~/.sushi/bento/ |
Packages installed globally (outside any project) |
~/.sushi/bin/ |
Symlinks to package executables, add to PATH for access |
~/.sushi/cache/ |
Cached .nori archives from installations |
.sushi_bento/ |
Per-project symlinks into the global store |
Archive Format¶
.nori files are gzip-compressed tarballs. The internal structure uses a version-prefixed directory:
my-package-1.0.0/
nori.toml
lib/
mylib.slib
bin/
mytool
data/
config.toml
Archives can be inspected with standard tools:
tar tzf my-package-1.0.0.nori
Workflow Example¶
A complete workflow for creating and distributing a Sushi library:
# 1. Write your library
cat > mathlib.sushi << 'EOF'
public fn add(i32 a, i32 b) i32:
return Result.Ok(a + b)
public fn multiply(i32 a, i32 b) i32:
return Result.Ok(a * b)
EOF
# 2. Compile to .slib
./sushic --lib mathlib.sushi -o build/mathlib.slib
# 3. Create manifest
nori init
# Edit nori.toml to add: libraries = ["build/mathlib.slib"]
# 4. Build the package
nori build
# 5. Install locally
nori install ./dist/math-lib-1.0.0.nori
# 6. Verify
nori list
nori info math-lib
# 7. Use in a program (compiler finds it automatically)
./sushic program.sushi -o program
Command Reference¶
| Command | Description |
|---|---|
nori --version |
Show version information |
nori init |
Create a template nori.toml in the current directory |
nori build |
Build a .nori archive from the current directory's manifest |
nori install |
Restore all dependencies listed in nori.toml (project context) |
nori install <archive> |
Install from a .nori file (project-local if in project, else global) |
nori install <name> from <path> |
Install from a directory or archive source |
nori install --global <archive> |
Force global install, skip nori.toml update |
nori search <query> |
Search Omakase for packages matching the query |
nori search <query> --page <n> |
Paginate search results |
nori search <query> --limit <n> |
Set results per page |
nori list |
List project-local packages (or global if outside a project) |
nori list --global |
List globally installed packages |
nori info <name> |
Show details about an installed package |
nori remove <name> |
Remove package from project and update nori.toml |
nori remove --global <name> |
Remove globally installed package |
Limitations¶
- No build step: Nori does not compile Sushi source. Use
sushicto compile first. - Local sources only: Remote installation via
nori install(HTTP, Omakase) is not yet available. Usenori searchto find packages, then install from local archives. - No version constraint syntax:
[dependencies]records exact versions only; range specifiers (^1.0,>=0.2) are not supported. - Platform-specific:
.slibfiles are not portable across platforms (same as the compiler). - No transitive dependency resolution: If package A depends on package B, you must install both explicitly.
See Also¶
- Libraries - Creating and linking Sushi libraries
- Library Format -
.slibbinary format specification - Compiler Reference - All compiler CLI options
- Getting Started - Introduction to Sushi