2 unstable releases
Uses new Rust 2024
| 0.2.0 | Sep 9, 2025 |
|---|---|
| 0.1.0 | Aug 31, 2025 |
#110 in Operating systems
53 downloads per month
100KB
2.5K
SLoC
pkgs
Use symbolic links to manage the installation of different packages.
Development background
Managing configuration files
There has long been no unified solution for managing configuration files on Linux systems. The mainstream solutions today are Stow and Nix Home Manager. However, both have some unsatisfactory drawbacks.
Stow’s management approach is somewhat rigid — it requires storing full filesystem paths and lacks customization options. Nix Home Manager requires the Nix ecosystem and has a relatively high learning curve.
Managing Git packages
[!caution] This feature is still planned and has not yet been implemented.
Tools like mpv lack suitable package management when installing plugins, forcing users to manage them manually, which is cumbersome.
This project also plans to integrate Git version management to provide a way to manage Git-based packages.
Installation
cargo install pkgs-cli --locked
Usage guide
Create a descriptor file in the directory where the packages exist. Supports both TOML and YAML formats, as shown below:
pkgs.toml
# Optional `vars` section, used to define variables
# Use the ${var} syntax to reference variables
# If you reference other variables, they must be declared in order
[vars]
CONFIG_DIR = "${HOME}/.config" # HOME variable is built-in
APP_DIR = "${HOME}/Apps"
NU_DIR = "${CONFIG_DIR}/nushell"
# `packages` section is required; each table under it corresponds to a package,
# and should match a directory with the same name in the current directory
[packages.yazi]
kind = "local" # Package type, optional; defaults to "local". Currently only "local" is supported.
[packages.yazi.vars] # Package-local variables, visible only within the package
YAZI_DIR = "${CONFIG_DIR}/yazi"
[packages.yazi.maps] # Each entry under `maps` represents a mapping
"yazi.toml" = "${YAZI_DIR}/yazi.toml" # Left side can be a file inside the package
"my-custom" = "${YAZI_DIR}/plugins/my-plugin" # It can also be a directory
"keymap.toml" = "${YAZI_DIR}/keymap.toml" # Right side is the path where the symlink will be created
"yazi.nu" = "${NU_DIR}/autoload/" # If the mapped file has the same name,
# you can end the path with '/' to omit the filename.
[packages.nu.maps]
"config.nu" = "${NU_DIR}/"
pkgs.yaml / pkgs.yml
# Optional `vars` section, used to define variables
# Use the ${var} syntax to reference variables
# If you reference other variables, they must be declared in order
vars:
CONFIG_DIR: ${HOME}/.config # HOME variable is built-in
APP_DIR: ${HOME}/Apps
NU_DIR: ${CONFIG_DIR}/nushell
# `packages` section is required; each table under it corresponds to a package,
# and should match a directory with the same name in the current directory
packages:
yazi:
kind: local # Package type, optional; defaults to "local". Currently only "local" is supported.
vars: # Package-local variables, visible only within the package
YAZI_DIR: ${CONFIG_DIR}/yazi
maps: # Each entry under `maps` represents a mapping
yazi.toml: ${YAZI_DIR}/yazi.toml # Left side can be a file inside the package
my-custom: ${YAZI_DIR}/plugins/my-plugin # It can also be a directory
keymap.toml: ${YAZI_DIR}/keymap.toml # Right side is the path where the symlink will be created
yazi.nu: ${NU_DIR}/autoload/ # If the mapped file has the same name,
# you may end with / and omit the filename
nu:
maps:
config.nu: ${NU_DIR}/
The following commands are supported:
pkgs list # List all packages
pkgs load --all # Load all packages
pkgs load yazi nu # Load only yazi and nu
# After `load`, if you modify the configuration file you can run `load` again to reapply; `unload` is not required
pkgs unload --all # Unload all packages
pkgs unload yazi nu # Unload only yazi and nu
pkgs schema # Generate json schema for descriptor file
Behavior
The load command creates symbolic links at the specified locations that point to the corresponding files' absolute paths according to the configuration file (so if a file path changes because of variables, you must load again). If an error occurs while loading a package, the operation for that package will be rolled back. After loading completes, the created symlinks are recorded in .pkgs/trace.toml in the current directory — please do not modify or delete this file.
If a parent directory for a target path does not exist during loading, the tool will create all missing parent directories and notify the user.
The unload command removes packages by reading .pkgs/trace.toml. If an error occurs during unload, a rollback will also be performed.
[!warning] The order of variable loading and the creation of mappings within a package follow the order in the description file.
However, when loading or unloading packages, different packages are processed in lexicographical order rather than the order in the description file. Therefore, do not rely on the order between packages.
License
This project is open-source under the GPL-3.0 License. See LICENSE for details.
Dependencies
~3.5–5MB
~99K SLoC