Packages

Packages are the fundamental unit of code organization and sharing in Cell.

Package Structure

A package is a directory containing a cell.toml manifest:

mypackage/
├── cell.toml        # package manifest
├── main.ce          # entry point (optional)
├── utils.cm         # module
├── helper/
│   └── math.cm      # nested module
├── render.c         # C extension
└── _internal.cm     # private module (underscore prefix)

cell.toml

The package manifest declares metadata and dependencies:

package = "mypackage"
version = "1.0.0"

[dependencies]
prosperon = "gitea.pockle.world/john/prosperon"
mylib = "/Users/john/work/mylib"

Fields

  • package — canonical package name
  • version — semantic version
  • dependencies — map of alias to package locator

Module Resolution

When importing with use(), Cell searches in order:

  1. Local package — relative to package root
  2. Dependencies — via aliases in cell.toml
  3. Core — built-in Cell modules
// In package 'myapp' with dependency: renderer = "gitea.pockle.world/john/renderer"

use('utils')           // myapp/utils.cm
use('helper/math')     // myapp/helper/math.cm
use('renderer/sprite') // renderer package, sprite.cm
use('json')            // core module

Private Modules

Files starting with underscore are private:

// _internal.cm is only accessible within the same package
use('internal')       // OK from same package
use('myapp/internal') // Error from other packages

Package Locators

Remote Packages

Hosted on Gitea servers:

gitea.pockle.world/user/repo

Local Packages

Absolute filesystem paths:

/Users/john/work/mylib

Local packages are symlinked into the shop, making development seamless.

The Shop

Cell stores all packages in the shop at ~/.cell/:

~/.cell/
├── packages/
│   ├── core -> gitea.pockle.world/john/cell
│   ├── gitea.pockle.world/
│   │   └── john/
│   │       ├── cell/
│   │       └── prosperon/
│   └── Users/
│       └── john/
│           └── work/
│               └── mylib -> /Users/john/work/mylib
├── lib/
│   ├── local.dylib
│   └── gitea_pockle_world_john_prosperon.dylib
├── build/
│   └── <content-addressed cache>
├── cache/
│   └── <downloaded zips>
├── lock.toml
└── link.toml

lock.toml

Tracks installed package versions:

[gitea.pockle.world/john/prosperon]
type = "gitea"
commit = "abc123..."
updated = 1702656000

link.toml

Development links override package resolution:

[gitea.pockle.world/john/prosperon]
target = "/Users/john/work/prosperon"

Installing Packages

# Install from remote
cell install gitea.pockle.world/john/prosperon

# Install from local path
cell install /Users/john/work/mylib

Updating Packages

# Update all
cell update

# Update specific package
cell update gitea.pockle.world/john/prosperon

Development Workflow

For active development, link packages locally:

# Link a package for development
cell link add gitea.pockle.world/john/prosperon /Users/john/work/prosperon

# Changes to /Users/john/work/prosperon are immediately visible

# Remove link when done
cell link delete gitea.pockle.world/john/prosperon

C Extensions

C files in a package are compiled into a dynamic library:

mypackage/
├── cell.toml
├── render.c      # compiled to mypackage.dylib
└── render.cm     # optional Cell wrapper

The library is named after the package and placed in ~/.cell/lib/.

See Writing C Modules for details.

Platform-Specific Files

Use suffixes for platform-specific implementations:

mypackage/
├── audio.c           # default implementation
├── audio_playdate.c  # Playdate-specific
└── audio_emscripten.c # Web-specific

Cell selects the appropriate file based on the build target.