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:
- Local package — relative to package root
- Dependencies — via aliases in
cell.toml - 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.