

Pakku
Package Manager for the Raku Programming Language.
Installation
Pakku needs Rakudo, libarchive, and something that speaks HTTPS: libcurl (loaded directly),
or the curl or wget binary (curl.exe ships with Windows, nothing to install there).
# Install
git clone https://github.com/hythm7/Pakku.git
cd Pakku
raku -I. bin/pakku add .
# Install using Zef
zef install Pakku
# Upgrade
pakku update Pakku
Usage
Pakku manages Raku distributions with commands like add, remove, update etc.
Full command consists of:
pakku [general-options] <command> [command-options] <dists>
There are two types of options:
General options:
These are the options that control the general behavior of Pakku, eg. specify the configuration file, run asynchronously or disable colors. The general options are valid for all commands, and must be placed before the command.
Command options:
These are the options that control the specified command, for example when installing a distributions one can add notest option to disable testing. these options must be placed after the command.
Ecosystems
Pakku gets its dists from where the dists live: the fez ecosystem (https://360.zef.pm).
Dists that never moved to fez are served from the Raku Ecosystem Archive (REA), which Pakku
only asks when fez has nothing to offer, and only loads then.
A recommendation manager (recman in Pakku speak) is either an ecosystem (mirrors serving an
index and tarballs) or a local directory of extracted dists. Each ecosystem publishes an index,
one JSON file with every META. Pakku keeps a copy under ~/.pakku/.index/<name>/ and resolves
names, versions and dependencies locally: search, info and dependency resolution never wait
for a server.
Index freshness:
pakku add dist # the index is refreshed when older than its refresh hours (fez 1, rea 24)
pakku refresh # refresh every index now
pakku refresh rea # just that one
pakku refresh add dist # refresh first, then add
pakku norefresh add dist # never touch the network for the index (offline, with the cache)
pakku nuke index # forget every index, the next command fetches fresh ones
A dist missing from an index older than ten minutes makes Pakku refresh once and look again, so a
dist uploaded a minute ago is not left waiting for the hour to pass.
An index is 10 to 20 MB of JSON. Pakku parses it once per refresh into small files under
~/.pakku/.index/<name>/derived (the names, the provided modules, and the METAs in 256 buckets by
name), so a lookup reads a few kilobytes and pakku search answers in the time it takes to start.
Being careful:
π¦ A fez tarball is named after its SHA-1 (the index says which), Pakku checks the download when sha1sum, shasum or certutil is around.
π¦ Downloads are not capped: a transfer that stalls for a minute is given up, a slow one is not.
π¦ Every pakku process works in its own .tmp and .stage directory under ~/.pakku, so two of them can run at once.
π¦ Archives are unpacked with suspicion: entries that try to escape the dist directory, links, device
files and lies about sizes are refused, and a half extracted dist is removed.
Recman config:
pakku config recman # view the recmans
pakku config recman rea disable # fez only
pakku config recman fez set refresh 24 # refresh fez once a day (true: always, false: never)
pakku config recman fez set mirrors https://mirror.example/,https://360.zef.pm/ # mirrors are tried in order
pakku config recman darkpan set mirrors /srv/darkpan/ priority 0 # a directory with an index.json and tarballs, asked first
pakku config recman mydists set location /home/me/dists # a local directory of extracted dists
pakku config recman mydists unset # bye
pakku config recman reset # back to fez and rea
An entry has a name, a type (ecosystem or local, guessed from mirrors or location when
not set), mirrors and an index file name (index.json) with a source (path, as fez does
it, or source-url, as REA does it) for ecosystems, a location for local ones, refresh hours,
a priority (lower first) and active.
Pakku Commands
add
Install distributions
options:
deps β all dependencies
deps < build > β build dependencies only
deps < test > β test dependencies only
deps < runtime > β runtime dependencies only
deps < only > β install dependencies but not the dist
exclude < Spec > β exclude Spec
test β test distribution
xtest β xTest distribution
build β build distribution
serial β add distributions in serial order
contained β add distributions and all transitive deps (regardless if they are installed)
precomp β precompile distribution
to < repo > β add distribution to repo < home site vendor core /path/to/MyApp >
nodeps β no dependencies
nobuild β bypass build
notest β bypass test
noxtest β bypass xtest
noserial β no serial
noprecomp β no precompile
Examples:
pakku add dist # add dist
pakku add notest dist # add dist without testing
pakku add nodeps dist # add dist but dont add dependencies
pakku add serial dist # add dists in serial order
pakku add deps only dist # add dist dependencies but dont add dist
pakku add exclude Dep1 dist # add dist and exclude Dep1 from dependencies
pakku add noprecomp notest dist # add dist without testing and no precompilation
pakku add contained to /opt/MyApp dist # add dist and all transitive deps to custom repo
pakku add to vendor dist1 dist2 # add dist1 and dist2 to vendor repo (force: even if they are installed elsewhere)
pakku add ./dist # a directory with a META6.json
pakku add ./dist-1.0.tar.gz # a tarball
pakku add https://host/dist-1.0.tar.gz # a tarball by URL
pakku add https://github.com/user/dist.git#v1.0 # a git repository (#tag, #branch or #sha, needs git)
pakku add 'dist:ver(* > 1.2):auth' # a spec with a selector, see Specs below
dist is a name in the ecosystem, ./dist is a directory: paths start with ./ or / (your shell expands ~).
remove
Remove distributions
options:
from < repo > β remove distribution from provided repo only
Examples:
pakku remove dist # remove dist from all repos
pakku remove from site dist # remove dist from site repo only
list
List installed distributions
options:
details β details
repo < name-or-path > β list specific repo
Examples:
pakku list # list all installed dists
pakku list dist # list installed dist
pakku list details dist # list installed dist details
pakku list repo home # list all dists installed to home repo
pakku list repo /opt/MyApp # list everything installed in custom repo
search
Search the ecosystems, locally and instantly
options:
latest β the newest release of each dist and author (default)
nolatest β every release
relaxed β dist is anywhere in the name, case ignored (default)
norelaxed β the exact name
details β dependencies, provides, source and recman of each hit
count < number > β number of dists to be returned
Examples:
pakku search dist # dists whose name contains dist, newest release per author
pakku search nolatest dist # every release ever published
pakku search norelaxed dist # the exact name only
pakku search count 4 dist # at most 4
pakku search details dist # with details
pakku search 'dist:ver(* > 2)' # a spec narrows the releases
info
Everything about a dist: the newest release with its dependencies, provides and source, every
release by author, what is installed in which repo, and who depends on it
Examples:
pakku info dist
pakku info dist:auth
pakku i dist1 dist2
build
Build distributions
options:
timeout < seconds > β kill a build quiet for that long (default 420, 0 never)
Examples:
pakku build dist
pakku build .
pakku build ./dist-1.0.tar.gz
test
Test distributions
options:
xtest β XTest distribution
build β Build distribution
noxtest β Bypass xtest
nobuild β Bypass build
timeout < seconds > β kill a test quiet for that long (default 420, 0 never)
Examples:
pakku test dist
pakku test ./dist
pakku test xtest ./dist
pakku test nobuild ./dist
pakku test timeout 1200 ./dist
pakku test https://github.com/user/dist.git
update
Update distributions to latest version
options:
clean β clean not needed dists after update
deps β update dependencies
nodeps β no dependencies
exclude Dep1 β exclude Dep1
deps only β dependencies only
build β build distribution
nobuild β bypass build
test β test distribution
notest β bypass test
xtest β xTest distribution
noxtest β bypass xtest
precomp β precompile distribution
noprecomp β no precompile
noclean β dont clean unneeded dists
in < repo > β update distribution and install in repo < home site vendor core /path/to/MyApp >
Examples:
pakku update # update all installed distribution
pakku update dist
pakku update nodeps dist
pakku update notest dist1 dist2
state
Check the state of installed distributions
options:
updates β check updates for dists
clean β clean older versions of dists
noupdates β dont check updates for dists
noclean β dont clean older versions
Examples:
pakku state
pakku state dist
pakku state clean dist
pakku state noupdates dist
download
Download distribution source
Examples:
pakku download dist # download dist and extract to temp directory
refresh
Refresh the ecosystem indexes without waiting for them to go stale
Examples:
pakku refresh # every active ecosystem
pakku refresh rea # one of them
pakku refresh add dist # the general option: refresh, then add
nuke
Nuke directories
Examples:
pakku nuke cache # nuke cache
pakku nuke index # nuke the ecosystem indexes (refreshed on next use)
pakku nuke pakku # nuke pakku home directory (cache, indexes, config)
pakku nuke home # nuke home repo
pakku nuke site # nuke site repo
pakku nuke vendor # nuke vendor repo
pakku force nuke core # nuke the core repo, Rakudo's own modules (you have been warned)
config
Each Pakku command like add, remove, search etc. corresponds to a config module with the same name in the config file.
one can use config command to enable, disable, set, unset an option in the config file.
Values keep their type: set count 42 stores a number, set mirrors a/,b/ a list.
options:
enable β enable option
disable β disable option
set < value > β set option to value
unset β unset option
reset β back to the default
Examples:
pakku config # view all config modules
pakku config new # create a new config file
pakku config add # view add config module
pakku config add precompile # view precompile option in add config module
pakku config add enable xtest # enable option xtest in add module
pakku config add set to home # set option to to home (change default repo to home) in add module
pakku config test set timeout 1200 # patience for slow test suites
pakku config pakku enable async # enable option async in pakku module (general options)
pakku config pakku unset verbose # unset option verbose in pakku module
pakku config recman rea disable # disable recman named rea in recman module
pakku config recman fez set refresh 24 # set recman fez's refresh hours
pakku config recman mine set mirrors https://a/ # a new ecosystem recman named mine
pakku config add reset # reset add config module to default
pakku config reset # reset all config modules to default
help
Get help on a specific command
Examples:
pakku
pakku help add
pakku help list
pakku help remove
pakku add
pakku help
pakku help help
Pakku General Options
Options:
pretty β use colors
force β use force
async β run asynchronously (disabled by default because some dists tests are not async safe)
dont β do everything but dont do it (dry run)
bar β use progress bar
spinner β use spinner
verbose < level > β verbosity < nothing error warn info now debug all >
cores < number > β number of cores used when run in async mode
config < path > β specify config file
cache < path > β cache downloaded dists there
recman β enable all recommendation managers
recman < MyRec > β use MyRec recommendation manager only
norecman β disable all recommendation managers (the cache still answers)
norecman < MyRec > β use all recommendation managers except MyRec
refresh β refresh the ecosystem indexes first
norefresh β never refresh the ecosystem indexes (offline)
nopretty β no colors
noforce β no force
nobar β no progress bar
nospinner β no spinner
noasync β dont run asynchronously
nocache β disable cache
yolo β proceed if error occured (eg. test failure)
please β be nice to butterflies
Examples:
pakku async add dist # run in async mode while adding dist
pakku nocache add dist # dont use cache
pakku dont add dist # dont add dist (dry run)
pakku norefresh add dist # offline, what the index and the cache already know
pakku pretty please remove dist
Specs
A dist is asked for by name, with Raku's own adverbs. Inside <> is a string, inside () is a
selector, exactly as in a use statement:
dist # whatever is newest
dist:ver<1.2> # 1.2, 1.2.3, 1.2.anything: a version string is a prefix (Raku's rule)
dist:ver<1.2+> # 1.2 or newer
dist:ver<1.*> # any 1.x
dist:auth # by that author, auth for any author on zef
dist:api<2>
dist:ver(* > 1.2) # a selector: anything Raku can smartmatch a version against
dist:ver(1.2 .. 2) # a range, numbers inside ver( ) and api( ) are versions
dist:ver(v1.2 | v1.4) # a junction
dist:ver(all(* >= 1.2, * < 2)) # both; any( ) and none( ) likewise
dist:ver(v1.2 ..^ v2) # or a range
dist:auth(/^ zef /) # a regex
dist:ver(Any) # anything, really
Selectors are parsed and evaluated by Raku itself, with one rule: they are data, not code.
Literals, versions, ranges, junctions, regexes, * and the comparison and junction operators
are welcome; blocks, calls and variables are refused, because a spec also comes from other
people's META files and from the ecosystem index, and nobody wants pakku search running
somebody else's code. Quote the spec in a shell: pakku add 'dist:ver(* > 1.2)'. One * per selector: * > 1 & * < 2,
and (* > 1) & (* < 2) too, is a single piece of code with two stars as far as Raku is concerned
(junction and logical operators curry), so Pakku refuses it; write all(* > 1, * < 2), any(...),
none(...) or a range.
The same specs work in META6.json depends, in every form S22 describes: plain strings, the hash
form (name, ver, auth, api, from, hints), any alternatives (the first one the ecosystem
can serve wins), runtime / build / test phases with requires / recommends / suggests
(only requires are required), a list inside the alternatives (all of those), one dependency object
as the whole depends, by-distro.name, by-kernel.name, by-env.VAR, by-raku.version and friends,
and :from<bin>, :from<native>, :from<Perl5> for what Pakku can check but not install. A version
with a leading v is what Rakudo makes of it: v2.0 is a different version from 2.0, for pakku and
for use alike.
[!NOTE]
Rakudo itself still turns the selector of a use dist:ver(...) into a plain string at run time.
Pakku honours selectors when resolving and installing; what use does with them is Rakudo's call.
Feeling Rakuish Today?
Most of Pakku commands and options can be written in shorter form, straight from the grammar:
commands
add β a β update β u up β remove β r list β l βͺ search β s π build β b
test β t download β d nuke β n state β st config β cnf refresh β rfr π
info β i βΉ help β h β
general options
pretty β p nopretty β np force β f noforce β nf bar β b nobar β nb
spinner β s nospinner β ns verbose β v π cache β c nocache β nc recman β rec
norecman β nrec norefresh β nrfr async β sync noasync yolo β y Β―\_(γ)_/Β―
command options
deps β d nodeps β nd only β o exclude β x build β b nobuild β nb
test β t notest β nt xtest β xt noxtest β nxt serial β s noserial β ns
contained β c nocontained β nc precomp β p noprecomp β np details β d nodetails β nd
latest β l nolatest β nl relaxed β r norelaxed β nr count β c clean β c
noclean β nc updates β up noupdates β nu from β f
verbosity
nothing β N 0 error β E 1 warn β W 2 info β I 3 now β 4 π¦ debug β D 5 all β A 6 π
The below are Pakku commands as well!
pakku π π§ β dist
pakku βͺ
pakku β
pakku π
ENV Options
Options can be set via environment variables as well. Booleans take true, false, yes, no,
on, off, 1 or 0.
General
PAKKU_VERBOSE PAKKU_CACHE PAKKU_RECMAN PAKKU_NORECMAN PAKKU_REFRESH PAKKU_CONFIG PAKKU_DONT
PAKKU_FORCE PAKKU_PRETTY PAKKU_BAR PAKKU_SPINNER PAKKU_ASYNC PAKKU_CORES PAKKU_YOLO
PAKKU_CACHE takes true, false or the path of the cache directory.
Add
PAKKU_ADD_TO PAKKU_ADD_DEPS PAKKU_ADD_TEST PAKKU_ADD_BUILD PAKKU_ADD_XTEST
PAKKU_ADD_SERIAL PAKKU_ADD_CONTAINED PAKKU_ADD_PRECOMPILE PAKKU_ADD_EXCLUDE
Test
PAKKU_TEST_BUILD PAKKU_TEST_XTEST PAKKU_TEST_TIMEOUT
Build
PAKKU_BUILD_TIMEOUT
Remove
PAKKU_REMOVE_FROM
List
PAKKU_LIST_REPO PAKKU_LIST_DETAILS
Search
PAKKU_SEARCH_LATEST PAKKU_SEARCH_DETAILS PAKKU_SEARCH_RELAXED PAKKU_SEARCH_COUNT
Update
PAKKU_UPDATE_IN PAKKU_UPDATE_DEPS PAKKU_UPDATE_TEST PAKKU_UPDATE_XTEST PAKKU_UPDATE_BUILD
PAKKU_UPDATE_CLEAN PAKKU_UPDATE_PRECOMPILE PAKKU_UPDATE_EXCLUDE
State
PAKKU_STATE_CLEAN PAKKU_STATE_UPDATES
Pakku Output
Pakku output aims to be tidy and concise, uses emojis, colors and three letters key words to convey messages.
For example, the π¦ emoji indicates that Pakku is starting a task, while π§ means Pakku successfully completed a task.
An output line like:
π¦ BLD: ο½’Inline::Perl5:ver<0.60>:auth<cpan:NINE>:api<>ο½£
means Pakku is starting to build Inline::Perl5:ver<0.60>:auth<cpan:NINE>:api<>, and based on the result another output line could be:
π§ BLD: ο½’Inline::Perl5:ver<0.60>:auth<cpan:NINE>:api<>ο½£ # build success
π¦ BLD: ο½’Inline::Perl5:ver<0.60>:auth<cpan:NINE>:api<>ο½£ # build failure
Below is a list of output lines that one can see and their meaning:
π§ ADD β start add command
π¦ SPC β processing Spec
π¦ MTA β processing Meta
π¦ IDX β refreshing an ecosystem index
π¦ FTC β fetching
π¦ BLD β building
π¦ STG β staging
π¦ CMP β compiling a module
π¦ TST β testing
π§ IDX β index refreshed
π§ RFR β indexes to refresh
π§ BLD β build success
π§ TST β test success
π§ BIN β binary added
π§ INF β info about a dist
π§ VER β the releases of a dist
π§ REP β installed in that repo
π§ REV β a dist that depends on it
π WAI β waiting
π TOT β timed out
π OLO β yolo: an error was ignored
π¦ SPC β error processing Spec
π¦ MTA β error processing Meta
π¦ IDX β no usable index
π¦ FTC β fetch failure
π¦ ARC β archive refused
π¦ BLD β build failure
π¦ TST β test failure
π¦ CNF β config error
π¦ CMD β command error
Pakku verbosity levels:
- 0 `ο½’nothingο½£` β Nothing
- 1 `ο½’errorο½£` π¦ β Errors only
- 2 `ο½’warn ο½£` π β Warnings and errors
- 3 `ο½’info ο½£` π§ β Important things only (default)
- 4 `ο½’ now ο½£` π¦ β What is happening now
- 5 `ο½’debugο½£` π β Debug output
- 6 `ο½’ all ο½£` π β All available output
[!WARNING]
Pakku uses emoji and ANSI escape codes, If your terminal doesn't support them, you can disable colors, bars and spinners, (eg. pakku nopretty nobar nospinner add Foo), or disable permanently in config file. also for emojis, eg. to change the debug emoji for example, in config file replace "debug": {"prefix": "π"} with "debug": {"prefix": "D"}.
Command result:
-Ofun - SuccessNofun - Failure
Gotchas
Index freshness
Pakku resolves against its local copy of the ecosystem index, refreshed when older than the
recman's refresh hours. A dist released a moment ago may not be there yet: pakku refresh, or
pakku refresh add dist, fetches a fresh index first. The opposite, pakku norefresh add dist,
is how one stays offline with what the index and the cache already know. The cache is only asked
when the index cannot answer, so a cached old version never hides a newer release.
Pakku installs to site repo by default
If the user doesn't have rw permision to site repo, one can change the default repo to home in config file using:
pakku config add set to home
or specify the repo in the command e.g. pakku add to home dist
Paths look like paths
pakku add dist asks the ecosystem for dist, pakku add ./dist adds the directory. A path
starts with ./ or / (your shell expands ~), a tarball ends with .tar.gz, a git repository with .git.
Version names
Pakku releases are butterflies π¦ ava, bellona, caria, celastrina, chou ... in alphabetical
order, so the newest always sorts last. The why and the what of each name, and why an error is a
cricket π¦, is in versions.
Credits
Thanks to Panda and Zef for Pakku inspiration.
also Thanks to the nice #raku community.
Motto
Light like a π§, Colorful like a π§
Author
Haytham Elganiny elganiny.haytham at gmail.com
Copyright and License
Copyright 2026 Haytham Elganiny
This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.