On this page
Quick start
This page takes you from an empty directory to a working .peipkg in about five minutes. You will write a two-file recipe, run pekit build, inspect the staged output, then run pekit package and look inside the artifact it writes. At the end you have a complete, minimal recipe you can grow into a real one.
Prerequisites
- A
pekitbinary on yourPATH. Pekit is a single binary built from its source repository withgo build ./cmd/pekit; there is no separate installer. Note that pekit has no--helpor version banner — the docs are the manual. - A POSIX shell (
sh). Target commands run undersh -euc; any Linux system has this. zstdandtar, for the final inspection step only.
Create the recipe
A recipe is a directory, and only one file in it is required: pekit.toml. Make a directory and write the recipe:
$ mkdir hello && cd hello
# hello/pekit.toml
out_dir = "out"
[build]
command = '''
mkdir -p "$PEKIT_OUT/bin"
printf '#!/bin/sh\necho "Hello from Peios"\n' > "$PEKIT_OUT/bin/hello"
chmod +x "$PEKIT_OUT/bin/hello"
'''
Two things are going on here:
out_dirnames the directory pekit manages, relative to the recipe. Everything pekit stages or writes lands under it, andpekit cleanmay remove it wholesale — keep nothing precious there.[build]in this bare form defines a single build target namedmain. Itscommandis an ordinary shell script; pekit runs it with a set ofPEKIT_*environment variables exported, of which the important one is$PEKIT_OUT— the target's own staging directory. A build's job is to put its artifacts in$PEKIT_OUT. Here the "build" just writes a shell script; a real recipe would runmake,cargo build, or similar and copy the results in.
This recipe has no [source] section, so it builds against its own directory. Fetching real source trees is covered in Sources.
Run the build
From hello/ (or any directory beneath it — pekit walks upward to find the nearest pekit.toml):
$ pekit build
You should see three timestamped lines, ending in success:
[14:30:01] [build] loaded recipe
[14:30:01] [main] running target
[14:30:01] [main] target succeeded
Nothing else prints because the build command itself is silent; anything your build writes to stdout or stderr is streamed through with a [build:main] prefix. Pekit exits 0 on success and 1 on any error.
Inspect the staged output
Each build target stages into out/build/<target>/. Look at what the run produced:
$ find out -type f
out/.pekit/dependencies/build.main.json
out/build/main/bin/hello
out/build/main/ is target main's $PEKIT_OUT, and it now holds exactly what the command wrote (the out/.pekit/ entry is pekit's own bookkeeping). This staged tree is what packaging draws from. The script even runs:
$ out/build/main/bin/hello
Hello from Peios
Describe the package
Packaging is declared in a second file beside the recipe. Write hello/package.pekit.toml:
# hello/package.pekit.toml
format = "peipkg"
[package]
name = "hello"
version = "0.1.0-1"
architecture = "noarch"
description = "A friendly greeting."
license = "MIT"
[files]
":bin/hello" = "usr/bin/hello"
The peipkg format requires [package].version and [package].architecture; the rest of the metadata is optional. The [files] table maps sources to destinations: the left side ":bin/hello" is a build ref meaning "bin/hello from build target main's staged output", and the right side is where the file lands inside the package. Destinations must sit under the peipkg layout's permitted top levels (usr/bin/, usr/share/, etc/, and so on) — see Packaging files.
Write the package
$ pekit package
package stages the builds the package needs (re-running build.main), then writes the artifact:
[14:31:12] [package] loaded recipe
[14:31:12] [main] running target
[14:31:12] [main] target succeeded
[14:31:12] [main] wrote package: /home/you/hello/out/package/main-e33807f0ae9abdc7/hello_0.1.0-1_noarch.peipkg
The artifact is named <name>_<version>_<architecture>.peipkg and lands in a per-package stage directory under out_dir (the hash in the directory name is derived from the package's identity). Add --dry-run to any command to see this plan without writing anything.
Look inside
A .peipkg is a Zstandard-compressed tar archive: reserved .peipkg/ metadata entries followed by the payload as it will be installed.
$ zstd -d --stdout out/package/main-*/hello_0.1.0-1_noarch.peipkg | tar tf -
.peipkg/manifest.json
.peipkg/files.json
usr/
usr/bin/
usr/bin/hello
That file is a real package: peipkg can install it, and pekit publish can copy it to a configured destination. To start over, pekit clean removes the whole out/ directory.
Where to go next
- Anatomy of a recipe — every file in the recipe directory, all of
pekit.toml's sections, and the fullPEKIT_*environment contract. - Commands and targets — the seven commands, named targets,
needsordering, and target selection. - Invocation and flags — the command line:
--dry-run,--json, and how recipes are located. - Recipe format reference — the exhaustive schema for
pekit.tomland package files.