Package commands

ecko init                                  # scaffold ecko.json
ecko scaffold package my-pkg               # a whole package, ready to publish
ecko get github.com/ecko-lang/url            # fetch, vendor, pin
ecko get github.com/ecko-lang/url@v0.9.5     # a specific version
ecko install                               # rebuild vendor/ from the lockfile
ecko update [name...]                      # use `ecko get <path>@<version>` (see below)
ecko remove url                            # unvendor and unpin
ecko pack [-o out.zip]                     # bundle for distribution
ecko build file.ecko [-o app]              # single-file executable

init

Writes an ecko.json in the current directory. A program never needs one - a file is a program - but a manifest gives it a version and an entrypoint, a place for dependencies, and configuration readable as std.defaults.

get

Resolves straight from the forge; there is no index in the way.

ecko get github.com/ecko-lang/redis-client@v0.9.5

It vendors under vendor/, records the dependency, and pins a hash. The dependency key it writes is the name import binds: the last path segment with - mapped to _, so redis-client is recorded as redis_client. To use a different name, pass --as:

ecko get github.com/ecko-lang/redis-client --as redis

Re-running ecko get on a package keeps the alias you chose rather than adding a second entry for it. An alias already pointing at a different package is refused instead of repointed. Setting the key yourself in the manifest still works, and is how a grant is attached:

{ "dependencies": { "redis": { "path": "github.com/ecko-lang/redis-client", "grant": ["net"] } } }

install

Rebuilds vendor/ from the lockfile and verifies every hash. This is the CI and fresh-clone command. It never changes a pin.

Verification needs an ecko.sum to check against. A project that has a lockfile but no ecko.sum is refused rather than installed unverified:

$ ecko install
Couldn't install from ecko.lock: no ecko.sum in /app - 3 package(s) cannot be
verified. Run `ecko get` to pin them, or `ecko install --allow-unverified` to
install without integrity verification.

ecko get writes the pins, and committing ecko.sum alongside ecko.lock is what makes the install reproducible. --allow-unverified installs anyway with a warning, for a project that predates the file; it is not what CI should run.

update

Not something Ecko does, and not something it is going to do. A fetched package bundles its own vendor/, so there is no dependency graph to re-resolve - a version only ever moves one package at a time, and ecko get <path>@<version> is how you move it. The command exists to say that rather than to leave you guessing at a name every other toolchain has.

Moving a version is deliberately explicit: ecko install rebuilds exactly what the lockfile records, so a build can never silently upgrade.

remove

Deletes the vendored copy and its manifest and lockfile entries. Because there is no global store, removing really removes it.

pack

ecko pack -o myapp.zip

A deterministic archive of the project and its vendor/ - same input, same bytes, so it can be checksummed and compared. Reach for it to hand-build a distributable zip for a package that isn't hosted on GitHub, or to test a release locally. The official packages don't go through pack: each one's own release workflow builds its archive directly instead, but the same rule applies either way - the archive has to carry vendor/ along with the manifest and sources, or a dependency that works in the author's checkout is missing for everyone who fetches it.

build

ecko build server.ecko -o server

Bundles the interpreter and your program into one executable with no runtime dependency. See Building an executable.

ecko add no longer exists

It was renamed to get when resolution moved to the forge. If you find ecko add in a guide, the guide is stale.