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.wynwyn 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:
[project]
name = "my-lib"
version = "0.1.0"
entry = "src/main.wyn"
[dependencies]
# packages this library itself depends on, if anyThe 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:
<name>.wyn(e.g.my-lib.wyn)src/<name>.wyn<repo>.wynsrc/main.wyn
Name your entry file to match, and mark the API you want callers to reach with pub:
// src/my-lib.wyn
pub fn greet(who: string) -> string {
return "hello ${who}"
}Consumers call it through the import name:
import my-lib
fn main() {
print(my-lib.greet("world"))
}Publishing = git push + git tag
There is no publish command. To release a version:
git add -A
git commit -m "Release v1.0.0"
git push
git tag v1.0.0
git push --tagsThat's the whole process. A consumer pins the release with @ref:
wyn add github.com/you/[email protected]Versioning with @ref
@<ref> is any git ref - a tag, branch, or commit SHA:
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 commitWhatever 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 args→github.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 samegit 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[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:
wyn bind /usr/include/curl/curl.h -o curl.wynThen 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, sowyn add curlworks out of the box without a package. Runwyn add --listfor 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:
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:
wyn add [email protected]:you/private-lib.git # scp-style (SSH)
wyn add ssh://[email protected]/you/private-lib.git # explicit ssh:// schemeIn 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-agentbeforewyn restoreruns.
Then wyn restore clones every dependency reproducibly with no prompts.
See Also
- Using Packages - add and import dependencies
- Package CI - set up CI for your package
- C FFI - write C bindings
- Modules - organize code into modules