Skip to main content
Learn how to manage dependencies, configure your program manifest, and work with local and network imports in Leo.

Program Manifest (program.json)

Every Leo project has a program.json manifest file that defines metadata and dependencies.

Basic Structure

program.json

Manifest Fields

The unique name of your program, must end with .aleo:
Must follow naming rules:
  • Start with a letter
  • Contain only ASCII alphanumeric characters and underscores
  • Not contain the keyword “aleo” in the name
  • Not be a reserved keyword
Semantic version of your program:
Follows Semantic Versioning: MAJOR.MINOR.PATCH
Human-readable description of your program:
Software license identifier:
Common options: MIT, Apache-2.0, GPL-3.0
External programs your code depends on:
Dependencies only needed for testing:

Dependency Types

Network Dependencies

Import deployed programs from the Aleo network:
Use in your code:
src/main.leo
Network dependencies are automatically fetched from the Aleo network and cached locally in ~/.aleo/registry/{network}/{program}/{edition}/.

Local Dependencies

Import programs from your local filesystem:
Project structure:
Local dependencies use relative paths from the project directory. Use ../ to reference sibling directories.

Local Aleo File Dependencies

Import compiled .aleo bytecode files:
The path must point to a .aleo file, not a directory. This is useful for pre-compiled dependencies.

Dependency Editions

Specify a specific version (edition) of a network dependency:
Without an edition, Leo fetches the latest version:

Dependency Resolution

Leo resolves dependencies in topological order:
1

Parse Manifest

Leo reads program.json and collects all dependencies:
2

Build Dependency Graph

Constructs a directed graph of program dependencies:
3

Fetch Dependencies

For each dependency:
  • Local: Read from filesystem
  • Network: Fetch from Aleo network and cache
4

Topological Sort

Orders programs so dependencies are compiled before dependents:

Circular Dependency Detection

Leo detects and rejects circular dependencies:
Circular dependencies are not allowed. Restructure your programs to have a directed acyclic dependency graph.

Working with Imports

Basic Import

Import an external program:

Using Imported Types

Access structs and records from imported programs:

Calling Imported Functions

Invoke functions from dependencies:
Use the program.aleo/item syntax to reference imported items.

Package Structure

Leo expects a specific directory structure:

Creating Packages

Initialize a new package:
This creates:
  • Package directory structure
  • program.json with defaults
  • Basic src/main.leo template
  • .gitignore file
  • Sample test file
From crates/package/src/package.rs:420-442:

Package Constants

Key directory names (from crates/package/src/lib.rs):

Dependency Caching

Cache Location

Network dependencies are cached in:
Example:

Disabling Cache

Force fresh dependency fetches:

Clearing Cache

Manually clear cached dependencies:
The cache improves build times by avoiding redundant network requests. Only disable it when debugging dependency issues.

Advanced Configuration

Multiple Dependencies

Combine local and network dependencies:

Test Dependencies

Separate dependencies for tests:
Test files automatically have access to both dependencies and dev_dependencies.

Dependency Conflicts

Leo detects conflicting dependencies:
Each dependency must have a unique name and consistent configuration across your dependency tree.

Program Size Limits

Programs have size limits (from crates/package/src/lib.rs):
Leo validates program size during compilation:

Best Practices

1

Use Semantic Versioning

Version your programs following semver:
  • MAJOR: Breaking changes
  • MINOR: New features, backwards compatible
  • PATCH: Bug fixes
2

Pin Critical Dependencies

Specify editions for production dependencies:
3

Document Dependencies

Add descriptions explaining why dependencies are needed:
4

Minimize Dependencies

Only include necessary dependencies to reduce:
  • Build times
  • Circuit size
  • Attack surface
5

Test Dependency Changes

Run full test suite after updating dependencies:

Troubleshooting

Dependency Not Found

Solutions:
  • Verify program name spelling
  • Check network connectivity
  • Confirm program exists on network
  • Try with --no-cache

Path Not Found

Solutions:
  • Verify relative path is correct
  • Check directory structure
  • Ensure program.json exists in target directory

Version Mismatch

Solutions:
  • Ensure program field in manifest matches actual program name
  • Check imported program names match manifest declarations

Next Steps