4.4 KiB
title, description, weight, type
| title | description | weight | type |
|---|---|---|---|
| Packages | Code organization and sharing in ƿit | 30 | docs |
Packages are the fundamental unit of code organization and sharing in ƿit.
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/
└── helpers.cm # private module (internal/ only)
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(), ƿit searches in order:
- Local package — relative to package root
- Dependencies — via aliases in
cell.toml - Core — built-in ƿit 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 in the internal/ directory are private to their package:
// internal/helpers.cm is only accessible within the same package
use('internal/helpers') // OK from same package
use('myapp/internal/helpers') // 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
ƿit 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
├── build/
│ └── <content-addressed cache (bytecode, dylibs, manifests)>
├── 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
pit install gitea.pockle.world/john/prosperon
# Install from local path
pit install /Users/john/work/mylib
Updating Packages
# Update all
pit update
# Update specific package
pit update gitea.pockle.world/john/prosperon
Development Workflow
For active development, link packages locally:
# Link a package for development
pit link add gitea.pockle.world/john/prosperon /Users/john/work/prosperon
# Changes to /Users/john/work/prosperon are immediately visible
# Remove link when done
pit link delete gitea.pockle.world/john/prosperon
C Extensions
C files in a package are compiled into per-file dynamic libraries stored in the content-addressed build cache:
mypackage/
├── cell.toml
├── render.c # compiled to ~/.cell/build/<hash>
└── physics.c # compiled to ~/.cell/build/<hash>
Each .c file gets its own .dylib at a content-addressed path in ~/.cell/build/. A per-package manifest maps module names to their dylib paths so the runtime can find them — see Dylib Manifests. A .c file and .cm file with the same stem at the same scope is a build error — use distinct names.
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
ƿit selects the appropriate file based on the build target.