# Made on Zaryn: four packages to try

> tinyhash (Python), @arvand/envguard (npm), portcheck (Rust) and humanize (Zig) are real tools published on Zaryn's registries, each installed with one command; how each was built, tested and published, to copy for your own.

Source: https://zaryn.xyz/docs/en/made-on-zaryn

Four small tools, one for each ecosystem, published on Zaryn the same way you would publish yours. Their code lives in Zaryn repositories under [arvand](/arvand), and every one installs with a single command and the tool you already use, from anywhere: the client checks every file against its hash.

```diagram
type: cards
title: Four packages, four ecosystems
---
🐍 | tinyhash · Python | short, stable fingerprints for files and folders: did anything change, is this the right download
📦 | @arvand/envguard · npm | your .env against .env.example: missing keys, empty values, secrets leaked into the example
🦀 | portcheck · Rust | is this port free, is that one reachable, and wait until it is
⚡ | humanize · Zig | bytes, durations, counts and times ago as people read them, without an allocator
```

## Try them

```bash
# tinyhash (Python)
pip install --index-url https://api.zaryn.xyz/v1/packages/pypi/all/simple/ tinyhash
tinyhash --tree data/

# @arvand/envguard (npm)
npx --@arvand:registry=https://api.zaryn.xyz/v1/packages/npm/ @arvand/envguard
npx @arvand/envguard --ci

# portcheck (Rust)
cargo install --index sparse+https://api.zaryn.xyz/v1/packages/cargo/index/ portcheck
portcheck --wait db:5432

# humanize (Zig)
zig fetch --save https://api.zaryn.xyz/v1/packages/zig/humanize/humanize-0.1.0.tar.gz
```

Each package page: [tinyhash](/packages/pypi/tinyhash) · [envguard](/packages/npm/@arvand/envguard) · [portcheck](/packages/cargo/portcheck) · [humanize](/packages/zig/humanize)

The same commands appear on the [Packages page](/packages#made-on-zaryn), with a copy button.

```diagram
type: flow
title: The way each of them went
---
Code | A Zaryn repository: zev init, zev commit, zev push | accent | 📁
~ tests pass
Build | python -m build, npm pack, cargo package, a zig tarball | | 🔨
~ a publish-only token
Publish | twine upload, npm publish, cargo publish, a zig archive upload, to Zaryn's registry | good | 🚀
~ anyone, anywhere
Install | pip, npx, cargo, zig fetch: every file checked against its hash | good | ✅
```

## tinyhash (Python)

Short BLAKE2b fingerprints, in base32, for files and folders.

```console
$ pip install --index-url https://api.zaryn.xyz/v1/packages/pypi/all/simple/ tinyhash
$ tinyhash --tree src/
uwulb2m4sffp  tinyhash/__init__.py
zmciwvuja5wy  tinyhash/cli.py
xubdz6t3q7rt  src/  (4 files)

$ tinyhash --check kxppivxcxam2 data/
✓ data/ matches kxppivxcxam2

$ tinyhash --diff old/ new/
+ extra.txt
- notes.md
~ core.py
1 added, 1 removed, 1 changed
```

The index above is Zaryn's single index: Zaryn's projects, and everything else from pypi.org, so other dependencies install as usual. `uv tool install --index … tinyhash` works too.

How it was made: the standard library only, Python 3.9 and later, 16 pytest tests, built with `python -m build` and published with `twine upload` and a publish-only token. Every step: [the Python publishing guide](/docs/en/publish-python-package).

## @arvand/envguard (npm)

```bash
npx --@arvand:registry=https://api.zaryn.xyz/v1/packages/npm/ @arvand/envguard
```

For a project, tell npm once where `@arvand` comes from, in `.npmrc`:

```ini
@arvand:registry=https://api.zaryn.xyz/v1/packages/npm/
```

```bash
npm install --save-dev @arvand/envguard
```

| Command | What it does |
|---|---|
| `envguard` | compare `.env` with `.env.example` |
| `envguard init` | write `.env.example` from your `.env`, keys only, safe to commit |
| `envguard --ci` | check the real environment (CI secrets) instead of a file |
| `envguard --strict` | also fail on empty values and keys missing from the example |
| `envguard --json` | the result as JSON |

A scoped name (`@arvand/…`) can only be published by its owner, so nobody can slip a package with the same name in front of it. How it was made: no dependencies, ES modules, Node 18 and later, 17 `node:test` tests, `npm publish` to Zaryn. Every step: [npm on Zaryn](/docs/en/packages-npm).

## portcheck (Rust)

```bash
cargo install --index sparse+https://api.zaryn.xyz/v1/packages/cargo/index/ portcheck
```

| Command | What it does |
|---|---|
| `portcheck 8080` | is port 8080 free on this computer? |
| `portcheck host:port` | can this computer reach it, and how fast? |
| `portcheck https://example.com` | URLs work: the port comes from the scheme |
| `portcheck --free 3000-3100` | the first free port in a range |
| `portcheck --wait db:5432` | wait until it answers (`--timeout 2m`) |

```bash
PORT=$(portcheck --free 3000-3100) npm run dev
portcheck --wait --timeout 2m postgres://db:5432 && ./migrate
```

How it was made: the standard library only, 9 tests, `cargo clippy` clean, `cargo publish --registry zaryn`. For a project, add Zaryn to `~/.cargo/config.toml` once and use `--registry zaryn`: [Rust crates on Zaryn](/docs/en/packages-rust).

## humanize (Zig)

```bash
zig fetch --save https://api.zaryn.xyz/v1/packages/zig/humanize/humanize-0.1.0.tar.gz
```

```zig
// build.zig
const humanize = b.dependency("humanize", .{});
exe.root_module.addImport("humanize", humanize.module("humanize"));
```

```zig
var buf: [32]u8 = undefined;
const size = try humanize.bytes(&buf, 1_572_864, .{}); // "1.5 MiB"
const took = try humanize.duration(&buf, 9045, .{});   // "2h 30m"
```

| Function | Gives |
|---|---|
| `bytes`, `parseBytes` | `1.5 MiB`, and `"10MB"` back to bytes |
| `duration`, `elapsed`, `parseDuration` | `2h 30m`, `1.3 µs`, and `"1h30m"` back to nanoseconds |
| `count`, `compact` | `1,234,567`, `3.4M` |
| `ago`, `ordinal`, `plural` | `3 minutes ago`, `21st`, `file`/`files` |

How it was made: no allocator (it writes into your buffer), tested on Zig 0.15 and 0.17, published as an archive whose hash `zig fetch` checks. Every step: [Zig packages on Zaryn](/docs/en/packages-zig).

## Make yours

```diagram
type: cards
title: Publishing your own, by ecosystem
---
🐍 | Python | python -m build, twine upload to Zaryn: the Python publishing guide
📦 | npm | npm publish with a scoped name you own: npm on Zaryn
🦀 | Rust | cargo publish --registry zaryn: Rust crates on Zaryn
⚡ | Zig | a tarball, checked by zig fetch: Zig packages on Zaryn
```

Create a publish token on the [Packages page](/packages) (it can only publish). Names are first come, first served. Public packages are free on every plan.
