Skip to content

Creating Packages

A Wyn package is just a git repo. There is no registry to upload to and no account to create. You structure a repo, push it to any git host, and tag a release. Anyone can then wyn add it by URL.

Package Structure

my-lib/
├── wyn.toml
├── src/
│   └── my-lib.wyn        # or my-lib.wyn / src/main.wyn - see resolution below
└── tests/
    └── test_my-lib.wyn

wyn init my-lib scaffolds this layout for you.

wyn.toml

A package carries a [project] block. If it has no dependencies of its own you can omit [dependencies] entirely:

toml
[project]
name = "my-lib"
version = "0.1.0"
entry = "src/main.wyn"

[dependencies]
# packages this library itself depends on, if any

The import-name convention

When someone runs wyn add github.com/you/my-lib, the last path segment (my-lib) becomes the import name unless they pass --as. Wyn then looks inside the cloned repo for the module source, in this order:

  1. <name>.wyn (e.g. my-lib.wyn)
  2. src/<name>.wyn
  3. <repo>.wyn
  4. src/main.wyn

Name your entry file to match, and mark the API you want callers to reach with pub:

wyn
// src/my-lib.wyn
pub fn greet(who: string) -> string {
    return "hello ${who}"
}

Consumers call it through the import name:

wyn
import my-lib

fn main() {
    print(my-lib.greet("world"))
}

Publishing = git push + git tag

There is no publish command. To release a version:

sh
git add -A
git commit -m "Release v1.0.0"
git push
git tag v1.0.0
git push --tags

That's the whole process. A consumer pins the release with @ref:

sh
wyn add github.com/you/[email protected]

Versioning with @ref

@<ref> is any git ref - a tag, branch, or commit SHA:

sh
wyn add github.com/you/[email protected]    # a release tag (recommended)
wyn add github.com/you/my-lib@main      # track a branch
wyn add github.com/you/my-lib@9f3a1c2   # pin an exact commit

Whatever the consumer requests, wyn.lock records the resolved commit SHA, so builds are reproducible even if a branch moves. Tag releases with vMAJOR.MINOR.PATCH so users have stable refs to pin.

Official vs third-party naming

  • Official packages live under github.com/wynlang/* and are addable by bare name: wyn add argsgithub.com/wynlang/args. The GitHub org membership is the "official" marker - there is no separate list.
  • Third-party packages are added by full path: wyn add github.com/you/my-lib. There is no gatekeeping and no approval step; publishing yours is exactly the same git push + tag.

C Binding Packages

A package that wraps a C library is also just a git repo - it carries an [ffi] block and the generated extern fn bindings:

cbind-curl/
├── wyn.toml        # [project] + [ffi] libs = "curl"
└── curl.wyn        # extern fn bindings
toml
[project]
name = "cbind-curl"
version = "0.1.0"

[ffi]
libs = "curl"
include_dirs = "/usr/include"

Generate the bindings from a C header with wyn bind:

sh
wyn bind /usr/include/curl/curl.h -o curl.wyn

Then git push + tag like any other package. When a project adds a C binding package, Wyn unions that package's [ffi] block into the link line automatically, so consumers get the correct -l flags with no extra config. See C FFI for the [ffi] fields and extern fn details.

A set of nine common C libraries (m, z, curl, sqlite3, crypto, ssl, curses, readline, xml2) ship as curated built-in recipes, so wyn add curl works out of the box without a package. Run wyn add --list for the current set.

Private Packages & Authentication

Wyn resolves dependencies by shelling out to git clone, so private repos work automatically through your ambient git authentication - anything that already lets you clone the repo from the command line works unchanged.

HTTPS with a stored token - configure a git credential helper (or a ~/.git-credentials entry / GIT_ASKPASS) once, then add by HTTPS URL:

sh
git config --global credential.helper store
# authenticate once with a token, e.g. via `gh auth login` or a manual clone
wyn add github.com/you/[email protected]

SSH - with an SSH key loaded in your agent, use an ssh:// or scp-style URL. Both forms are supported:

sh
wyn add [email protected]:you/private-lib.git         # scp-style (SSH)
wyn add ssh://[email protected]/you/private-lib.git   # explicit ssh:// scheme

In CI, make sure auth is non-interactive. Wyn cannot answer an interactive username/password prompt, so a bare private clone in CI would hang or fail. Configure one of:

  • a credential helper that reads a token from an environment secret, e.g.
    sh
    git config --global credential.helper \
      '!f() { echo "username=x-access-token"; echo "password=$GH_TOKEN"; }; f'
  • or an SSH deploy key added to ssh-agent before wyn restore runs.

Then wyn restore clones every dependency reproducibly with no prompts.

See Also

MIT License - v1.21.0