Files
cell/docs/packages.md

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:

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