Introduction
Declarch is a declarative wrapper for many package managers.
Short version:
- you list what you want,
- declarch maps it to backends,
declarch syncapplies it.
Why people use it
- One workflow for mixed ecosystems (
pacman,flatpak,npm,nix, etc). - Config-first style that is easier to review and version.
- Backend configs are flexible, so they can follow upstream package-manager changes.
What it is not
- Not a replacement for every backend CLI feature.
- Not guaranteed perfect on every backend/environment pair yet.
v0.8 note
v0.8 introduced breaking changes. If you are migrating, back up config first and start with preview.
cp -r ~/.config/declarch ~/.config/declarch.backup
declarch --dry-run sync
Path above is Linux-style. Use this to print real paths on your OS:
declarch info --doctor
One important behavior
declarch install expects explicit backend now.
Use backend:package or --backend <name>.
Start here
Installation
Pick one method.
Arch Linux (AUR)
paru -S declarch-bin
# or
yay -S declarch-bin
Linux/macOS (install script)
curl -sSL https://raw.githubusercontent.com/nixval/declarch/main/install.sh | sh
After install, it runs lightweight smoke checks (--help, info).
Do this for each of distro for easy to githubusercontent
decl init --backend aur paru yay pacman // for Arch distro base
decl init --backend nala apt // for Debian/ubuntu distro base
decl init --backend dnf5 // for Red Hat distro base
decl init --backend zypper // for SUSE distro base
decl init --backend brew // for macOS
// or you can custom it based on package manager preference
// I already manage it at nixval/package-manager
// or see the list at `decl init --list backend`
Windows (PowerShell, alpha preview)
irm https://raw.githubusercontent.com/nixval/declarch/main/install.ps1 | iex
Current status: alpha preview.
After install, it runs lightweight smoke checks (--help, info).
Still dont have the configuration, but possibly can configured to have winget, choco, scoop, etc.
Manual binary install
wget https://github.com/nixval/declarch/releases/latest/download/declarch-x86_64-unknown-linux-gnu.tar.gz
tar xzf declarch-x86_64-unknown-linux-gnu.tar.gz
sudo install declarch /usr/local/bin/
Build from source
cargo install declarch --git https://github.com/nixval/declarch
Source builds can be slower on first run because Cargo compiles the full dependency graph. If you want a faster setup path, prefer prebuilt release binaries via install script or package manager.
Verify
declarch --version
declarch --help
declarch info --doctor -v
Next: Quick Start
Quick Start
0) Understand the flow first (declarative)
Declarch works best when you treat KDL config as source of truth.
- Declare packages in module files.
- Preview with dry-run.
- Apply with sync.
declarch --dry-run sync
declarch sync
1) Initialize
declarch init
Expected structure:
~/.config/declarch/
├── declarch.kdl
├── backends/
└── modules/
└── base.kdl
Use this anytime to see actual config/state paths on your OS:
declarch info --doctor -v
2) Adopt backend(s) first
# Arch-based
declarch init --backend aur,paru,yay,pacman
# Debian/Ubuntu
declarch init --backend nala,apt
# Fedora/RHEL
declarch init --backend dnf5
# SUSE
declarch init --backend zypper
# macOS
declarch init --backend brew
# discover options from registry
declarch init --list backends
declarch init --list modules
3) Add packages (declarative first)
Example module file (~/.config/declarch/modules/mydotfiles.kdl):
meta {
title "My dotfiles"
}
pkg {
aur { hyprland waybar }
flatpak { firefox }
soar { gimp }
npm {
@opencode-ai/sdk
oh-my-opencode
}
}
Edit flow:
declarch edit
declarch edit mydotfiles --create
declarch edit mydotfiles
Then:
declarch --dry-run sync
declarch lint --fix
declarch sync prune
declarch sync
4) Direct install (optional shortcut)
declarch install aur:bat aur:fzf aur:ripgrep
declarch install npm:typescript
declarch install bat fzf ripgrep --backend aur
This writes package entries to modules/others.kdl automatically.
5) Add more backends when needed
declarch init --backend npm
declarch init --backend pnpm,yarn
# also valid
declarch init --backend pnpm yarn
That is the core workflow.
First Run (Linear Guide)
Use this if you want one straight path from zero to first successful sync.
1) Install declarch
Choose one method from Installation, then verify:
declarch --version
declarch --help
2) Initialize config
declarch init
If you are unsure where files are created on your OS:
declarch info --doctor
3) Add packages
Declarative-first path (recommended):
// ~/.config/declarch/modules/base.kdl
pkg {
aur { bat fd ripgrep }
npm { typescript }
}
Then apply with preview:
declarch --dry-run sync
declarch sync
Direct install shortcut (still valid):
declarch install aur:bat aur:fd aur:ripgrep
declarch install npm:typescript
// check it at `decl edit others`
Alternative: use one backend for all packages in a command:
declarch install bat fzf ripgrep --backend aur
4) Preview changes
declarch --dry-run sync
Review what will be installed/adopted/removed.
5) Apply
declarch sync
6) First troubleshooting loop
If a command fails, run this sequence:
declarch lint --mode validate
declarch info --doctor
declarch --dry-run sync
Then check Troubleshooting for targeted fixes.
Common Mistakes
1) Forgetting backend prefix on install
Symptom:
- package lands in unexpected backend block, or
- install command fails validation.
Fix:
declarch install aur:bat
# or
declarch install bat --backend aur
2) Running sync directly on first setup
Symptom:
- unexpected changes, or confusion about what will happen.
Fix: always preview first.
declarch --dry-run sync
declarch sync
3) Backend configured but binary not installed
Symptom:
- errors like
Package manager error: <binary> not found.
Fix:
declarch info <nameofthebackend>
// example
declarch info aur
Install missing binary or temporarily remove/disable that backend.
4) Editing KDL without validation
Symptom:
- parse error at sync/lint time.
Fix:
declarch lint --mode validate
5) Confusing config path vs state path
Symptom:
- editing one file while declarch reads another path.
Fix:
declarch info --doctor -v
Use the reported paths as source of truth.
6) Trying too many advanced flags at once
Symptom:
- hard to debug whether issue is from profile/host/modules/hooks.
Fix:
- start with plain
declarch --dry-run sync - add one flag at a time (
--profile, then--host, then modules)
Config Progression (Minimal -> Advanced)
This page shows a practical progression for you to start small and scale safely.
Stage 1: Minimal
declarch.kdl
imports {
"modules/base.kdl"
}
modules/base.kdl
pkg {
aur {
git
neovim
}
}
Use this stage to validate your first workflow:
declarch --dry-run sync
declarch sync
Stage 2: Add second backend
modules/base.kdl
pkg {
aur {
git
neovim
}
npm {
typescript
pnpm
}
}
Stage 3: Split by purpose (modular)
declarch.kdl
imports {
"modules/base.kdl"
"modules/development.kdl"
}
modules/development.kdl
pkg {
cargo {
ripgrep
fd-find
}
npm {
eslint
prettier
}
}
Stage 4: Advanced targeting (profile/host)
Use profile/host blocks for machine-specific or role-specific packages.
Example concept:
profile "work" {
pkg {
npm { @angular/cli }
}
}
host "laptop-1" {
pkg {
flatpak { com.discordapp.Discord }
}
}
Activate with:
declarch sync --profile work --host laptop-1
Rule of thumb
- Keep
base.kdlstable and small. - Add new modules only when package groups become hard to scan.
- Introduce profile/host targeting only after base + modules are clear.
Basic Concepts
1) Declarch is a wrapper
Declarch orchestrates real package managers.
You are still using actual tools under the hood (apt, pacman, flatpak, npm, nix, etc).
2) Agnostic design
You can mix ecosystems in one config:
pkg {
pacman { firefox git }
flatpak { org.mozilla.firefox }
npm { typescript }
}
3) Declarative loop
- declare packages
- run sync
declarch sync
4) Keep config portable first
If you copy your config to another machine (laptop, VPS, etc), it should still work with default sync:
declarch sync
No host or profile required. but if you want specify host and profile you can configure it.
5) Backend configs can evolve
Package managers change over time. Declarch backend definitions are designed to be editable and update-friendly.
6) Modules keep things simple
Use small files by context:
base.kdldev.kdlwork.kdlgaming.kdl
7) Optional profile/host layering
If you need machine-specific extras, you can opt in:
profile "work" {
pkg {
npm { @angular/cli }
}
}
host "laptop-1" {
pkg {
flatpak { com.discordapp.Discord }
}
}
```bash
declarch sync --profile work
declarch sync --host laptop-1
If you do not pass those flags, declarch uses your normal default config only.
8) Start safe
When unsure, use:
declarch --dry-run sync
Cross-OS (Alpha)
Declarch is designed to stay backend-agnostic, but cross-OS support is still in progress.
Current status:
- Linux: most tested path
- macOS: alpha preview
- Windows: alpha preview
This is still usable for early testing. Start with preview/doctor first.
Quick safety flow
declarch info --doctor
declarch --dry-run sync
info --doctor prints the actual config/state paths for your current OS.
Paths by OS
Declarch uses platform-native directories via Rust ProjectDirs.
Typical examples:
- Linux config:
~/.config/declarch - macOS config:
~/Library/Application Support/declarch - Windows config/state: under
%APPDATA%/%LOCALAPPDATA%equivalents (platform/runtime-dependent)
Use declarch info --doctor for exact paths on your machine.
Why this still works
- If a backend is not available for your OS, declarch warns and skips.
- Your config stays declarative and portable.
- You can still run the same
declarch syncflow on different machines.
Roadmap direction
- Better Windows backend coverage (
winget,choco,scoop) is planned. - More macOS validation (
brew+ mixed backends) is planned. - Warnings are designed to stay clear and easy to use.
Commands
This page maps current CLI behavior (declarch --help) into one practical guide.
Declarative-first mindset
Declarch is designed to be config-first:
pkg {
aur { bat fzf ripgrep }
npm { typescript }
}
Then apply:
declarch --dry-run sync
declarch sync
You can still use install for speed, but your source of truth stays in KDL modules.
Global flags (all commands)
-v, --verbose-q, --quiet-y, --yes-f, --force--dry-run--format table|json|yaml--output-version v1(for machine output contracts)
init
Usage:
declarch init [OPTIONS] [SOURCE]
Main usage:
declarch init
declarch init --backend npm
declarch init --backend apt,nala
declarch init --list backends
declarch init --list modules
SOURCE supports:
user/repouser/repo:variantuser/repo/branchgitlab.com/user/repohttps://...kdl- registry module name (example:
desktop/hyprland)
Important options:
--backend <NAME>...--list <backends|modules>--local(create local module, skip registry lookup)--host <NAME>--restore-declarch
install
Usage:
declarch install [OPTIONS] <PACKAGES>...
Examples:
declarch install aur:bat aur:fzf aur:ripgrep
declarch install npm:typescript
declarch install bat fzf ripgrep --backend aur
declarch install firefox --module browsers --backend aur
Options:
-b, --backend <BACKEND>-m, --module <MODULE>--no-sync
sync
Usage:
declarch sync [OPTIONS] [SUBCOMMAND]
Common flow:
declarch --dry-run sync
declarch sync
Core options (default sync + update + prune):
--target <TARGET>--profile <NAME>--host <NAME>--diff--noconfirm--hooks--modules <MODULES>
Subcommands:
declarch sync update
declarch sync prune
declarch sync cache --backend npm
declarch sync upgrade --backend npm --no-sync
Subcommand-specific options:
sync cache:-b, --backend <BACKEND>...sync upgrade:-b, --backend <BACKEND>...,--no-sync
Hook behavior and gating details are documented in: Policy, Hooks, and Editor Behavior.
search
Usage:
declarch search [OPTIONS] <QUERY>
Examples:
declarch search firefox
declarch search firefox -b aur,flatpak
declarch search npm:typescript
declarch search firefox --installed-only
declarch search firefox --available-only
declarch search firefox --local
declarch search firefox --limit all
Options:
-b, --backends <BACKENDS>--limit <NUM|all|0>--installed-only--available-only--local
info
Usage:
declarch info [OPTIONS] [QUERY]
Modes/examples:
declarch info
declarch info --doctor
declarch info --plan
declarch info --list
declarch info --list --scope all
declarch info --list --scope orphans
declarch info --list --scope synced
declarch info --list --scope unmanaged
declarch info aur:bat
Options:
--doctor--plan--list--scope all|orphans|synced|unmanaged--backend <BACKEND>--package <PACKAGE>--profile <NAME>--host <NAME>--modules <MODULES>
lint
Usage:
declarch lint [OPTIONS]
Examples:
declarch lint
declarch lint --mode validate
declarch lint --mode duplicates
declarch lint --mode conflicts --backend aur
declarch lint --diff
declarch lint --fix
declarch lint --strict
declarch lint --benchmark
State-related options:
declarch lint --repair-state
declarch lint --state-rm soar:firefox
declarch lint --state-rm package --state-rm-backend soar
declarch lint --state-rm-backend soar --state-rm-all
Main options:
--mode all|validate|duplicates|conflicts--backend <BACKEND>--diff,--fix,--strict,--benchmark--repair-state--state-rm <IDS>--state-rm-backend <BACKEND>--state-rm-all--profile <NAME>--host <NAME>--modules <MODULES>
edit
Usage:
declarch edit [OPTIONS] [TARGET]
Examples:
declarch edit
declarch edit mydotfiles --create
declarch edit mydotfiles --preview --number
declarch edit mydotfiles --validate-only
declarch edit mydotfiles --backup
Options:
-p, --preview--number(requires--preview)-c, --create--auto-format--validate-only-b, --backup
Editor resolution policy details: Policy, Hooks, and Editor Behavior.
switch
Usage:
declarch switch [OPTIONS] <OLD_PACKAGE> <NEW_PACKAGE>
Examples:
declarch switch neovim neovim-git
declarch switch firefox aur:firefox-nightly --backend aur
declarch switch firefox firefox-nightly --dry-run
Options:
--backend <BACKEND>
Hidden/internal commands
Not shown in main help, but available for advanced/internal workflows:
declarch self-update(script/manual install update path)declarch completions <shell>declarch ext
KDL Basics
Declarch config is written in KDL. This page only covers beginner syntax.
Minimal example
pkg {
pacman {
firefox
git
}
}
Rules to remember
- Blocks use
{}. - Package names are plain entries inside backend blocks.
- Quote string values in metadata/settings fields.
meta {
title "My Setup"
description "My daily packages"
}
Typical layout
imports {
"modules/base.kdl"
"modules/dev.kdl"
}
pkg {
pacman { firefox }
flatpak { org.mozilla.firefox }
npm { typescript }
}
Optional profile and host blocks
Use this only when you want extra packages for a specific situation. If you do not use these blocks, nothing changes in default behavior.
pkg {
aur { git curl }
}
profile "desktop" {
pkg {
aur { hyprland waybar }
}
}
host "vps-1" {
pkg {
aur { fail2ban tmux }
}
}
Activate them explicitly from CLI:
declarch sync --profile desktop
declarch sync --host vps-1
declarch sync --profile desktop --host vps-1
Need full syntax details? Use Syntax Reference (Advanced).
Backends
Backends are how declarch talks to package managers.
Think of it like this:
- declarch is the coordinator,
- backends do the real package operations.
Default + adopt model
declarch initcreates default backend definitions.declarch init --backend <name>adopts extra backends from registry.- Local backend files are editable.
Common backend groups
- System:
aur,pacman,flatpak,apt,nala,dnf,snap,nix,brew - Language/dev:
npm,pnpm,yarn,bun,cargo,pip,gem,go - Other:
soar
Planned Windows backends: winget, choco, scoop.
Add backend definitions
declarch init --backend npm
declarch init --backend pnpm,yarn
declarch init --backend pnpm yarn
Use backends in package config
pkg {
pacman { firefox }
flatpak { org.mozilla.firefox }
npm { typescript }
nix { nil }
}
Fallback concept
A backend can fallback when binary is missing. Examples:
nala -> aptaur -> pacman(when no AUR helper is available)paru -> pacmanyay -> pacman
Beginner tips
- Start small.
- Add one backend at a time.
- Keep backend files versioned in git.
- Sharing one config across laptop/VPS is okay.
- If a backend is not for your current OS, declarch will skip it and continue.
Modules
Modules help keep config readable.
Why modules?
Instead of one huge file, split by purpose:
base.kdl
dev.kdl
work.kdl
gaming.kdl
Create one
Beginner path (recommended):
declarch edit --create dev
Manual path (Linux example):
mkdir -p ~/.config/declarch/modules
cat > ~/.config/declarch/modules/dev.kdl << 'EOKDL'
pkg {
aur {
neovim
tmux
}
npm {
typescript
}
}
EOKDL
For macOS/Windows exact config path, check:
declarch info --doctor
Import it
imports {
"modules/base.kdl"
"modules/dev.kdl"
}
Template
meta {
title "Dev"
description "Development tools"
}
pkg {
aur {
// packages here
}
}
Practical tips
- One module = one context.
- Use obvious names.
- Keep each module short.
Minimal Setup
Smallest useful setup for beginners.
declarch.kdl
imports {
"modules/base.kdl"
}
modules/base.kdl
pkg {
aur {
neovim
git
}
}
Apply
declarch --dry-run sync
declarch sync
Why this is a good start
- only one module
- easy to read
- easy to expand later
Desktop Example
Simple desktop-oriented module layout.
Suggested structure
modules/
├── base.kdl
├── desktop.kdl
└── apps.kdl
modules/base.kdl
pkg {
aur {
neovim
bat
fzf
ripgrep
}
pacman {
git
curl
wget
}
}
modules/desktop.kdl
pkg {
aur {
hyprland
waybar
rofi-wayland
}
pacman {
foot
mako
grim
slurp
}
}
modules/apps.kdl
pkg {
pacman {
firefox
thunderbird
}
flatpak {
com.spotify.Client
org.telegram.desktop
}
}
declarch.kdl
imports {
"modules/base.kdl"
"modules/desktop.kdl"
"modules/apps.kdl"
}
Apply safely
declarch --dry-run sync
declarch sync
Development Example
Beginner-friendly dev setup with separate modules.
Prerequisite
declarch init --backend npm
Structure
modules/
├── base.kdl
├── dev.kdl
└── langs.kdl
modules/dev.kdl
pkg {
aur {
neovim
tmux
docker
}
pacman {
git
github-cli
jq
}
}
modules/langs.kdl
pkg {
aur {
rustup
}
npm {
typescript
ts-node
prettier
eslint
}
}
declarch.kdl
imports {
"modules/base.kdl"
"modules/dev.kdl"
"modules/langs.kdl"
}
Apply
declarch --dry-run sync
declarch sync
Modular Example
Organize by purpose, not by backend.
Example structure
modules/
├── core.kdl
├── work.kdl
├── gaming.kdl
└── media.kdl
core.kdl
pkg {
aur {
neovim
bat
fzf
}
pacman {
git
curl
}
flatpak {
org.mozilla.firefox
}
}
work.kdl
pkg {
pacman {
slack-desktop
zoom
}
flatpak {
com.microsoft.Teams
}
}
Select imports per machine
// work laptop
imports {
"modules/core.kdl"
"modules/work.kdl"
}
// gaming pc
imports {
"modules/core.kdl"
"modules/gaming.kdl"
"modules/media.kdl"
}
Why this pattern works
- cleaner diffs
- easier reuse
- machine-specific setups stay simple
Syntax Reference (Advanced)
Technical reference for KDL structures used by declarch.
If you are new, read:
Core blocks
meta { ... }
imports { ... }
pkg { ... }
Package declarations
Preferred (nested)
pkg {
pacman { firefox git }
flatpak { org.mozilla.firefox }
npm { typescript }
}
Also accepted (compatibility)
pkg:pacman { firefox git }
pkg {
pacman:firefox
npm:typescript
}
Optional advanced blocks
Backend options override
options:pacman {
noconfirm_flag "--noconfirm"
}
Env override
env:global {
"http_proxy=http://127.0.0.1:8080"
}
env:npm {
"NPM_CONFIG_REGISTRY=https://registry.npmjs.org"
}
Package source overrides (backend-specific)
repos:pacman {
"core"
"extra"
}
Hooks
hooks {
pre-sync "echo before"
post-sync "echo after"
}
To execute hooks, users must opt in:
experimental {
"enable-hooks"
}
And run sync with --hooks.
Policy
policy {
protected "linux" "systemd"
orphans "ask"
require_backend "true"
forbid_hooks "false"
on_duplicate "warn"
on_conflict "warn"
}
MCP policy (optional)
Default behavior is read-only for MCP actions. Enable write tools only when you explicitly trust your MCP client flow.
mcp {
mode "write-enabled"
allow_tools "declarch_sync_apply"
}
Profile and host blocks
These are optional overlays and are inactive by default.
profile "desktop" {
pkg { aur { hyprland waybar } }
}
host "vps-1" {
pkg { aur { fail2ban } }
}
Use from CLI:
declarch sync --profile desktopdeclarch sync --host vps-1
Validation notes
- Keep beginner config in nested
pkgstyle unless migration requires compatibility syntax. - Unknown keys may be ignored in some contexts for forward compatibility.
- Use
declarch lint --mode validateafter manual edits.
Custom Backends (Advanced)
This page documents custom backend authoring for backends/*.kdl under your declarch config directory.
File placement and import
- Create file (Linux example):
mkdir -p ~/.config/declarch/backends
$EDITOR ~/.config/declarch/backends/mypm.kdl
Use declarch info --doctor to print your exact config path on current OS.
- Import in
declarch.kdl:
backends {
"backends/mypm.kdl"
}
Minimal valid backend
backend "mypm" {
binary "mypm"
list "{binary} list" {
format "whitespace"
name_col 0
version_col 1
}
install "{binary} install {packages}"
remove "{binary} remove {packages}"
}
Required and optional fields
Required
backend "name" { ... }binary "..."(single or multiple)install "...{packages}..."
Strongly recommended
list "..." { ... }for state/introspectionremove "...{packages}..."search "...{query}..." { ... }
Optional commands
search_local "...{query}..." { ... }update "..."upgrade "..."cache_clean "..."noconfirm "-y"needs_sudo truefallback "other-backend"env KEY="VALUE"
"-" can be used on some commands to explicitly disable capability.
Optional meta block (recommended)
meta {
title "My Backend"
description "What this backend does"
kdl-maintainer "your-name"
tags "linux" "package-manager"
homepage "https://example.com"
platforms "linux"
requires "mybinary"
install-guide "https://example.com/install"
}
Compatibility:
- Canonical metadata keys:
kdl-maintainer,install-guide - Legacy metadata aliases:
maintainer,maintained,installation_guide
Placeholders
{binary}: resolved executable (supports multi-binary and fallback scenarios){packages}: space-separated package arguments{query}: search query text
If binary has multiple options, include {binary} in command templates.
Output format parsers
Supported format values:
whitespacetsvjsonjson_lines/jsonl/ndjsonnpm_jsonjson_object_keysregex
Whitespace example
list "{binary} -Q" {
format "whitespace"
name_col 0
version_col 1
}
JSON example (nested path)
list "{binary} list --json" {
format "json"
json {
path "dependencies"
name_key "name"
version_key "version"
}
}
Compatibility note: flat keys (json_path, name_key, version_key) are also accepted.
Search JSON example
search "{binary} search {query} --json" {
format "json"
json {
path "results"
name_key "name"
version_key "version"
desc_key "description"
}
}
Regex example
search "{binary} search {query}" {
format "regex"
regex "^([^\s]+)\s+-\s+(.+)$"
name_group 1
desc_group 2
}
Validation expectations
Backend validation enforces:
installmust include{packages}remove(if set) must include{packages}search/search_local(if set) should include{query}- parser-specific required keys must exist (e.g.
name_keyfor JSON list)
Fallback example
backend "nala" {
binary "nala"
fallback "apt"
list "{binary} list --installed" {
format "regex"
regex "^(\S+)/"
name_group 1
}
install "{binary} install -y {packages}"
remove "{binary} remove -y {packages}"
needs_sudo true
}
Testing checklist
# parse + config checks
declarch lint --mode validate
# backend visibility
declarch info
# optional search smoke test
declarch search mypm:foo --limit 5
Then run a limited dry-run sync:
declarch --dry-run sync --target mypm
Publishing
If backend works across environments, contribute to:
- https://github.com/nixval/declarch-packages
Debugging
This page is a practical troubleshooting playbook for config, state, and backend behavior.
Quick triage
Run these first:
declarch info --doctor
declarch info --list --scope all
declarch lint
declarch --dry-run sync
What this gives you:
info --doctor: runtime/config/state health checksinfo --list --scope all: everything tracked in statelint: config and consistency warnings--dry-run sync: planned install/adopt/prune actions before mutation
Lint for debugging (soft checks)
Use lint modes to isolate problem type quickly:
# syntax/import/basic structure
declarch lint --mode validate
# duplicate declarations
declarch lint --mode duplicates
# known config conflicts
declarch lint --mode conflicts
# inspect planned drift from current state
declarch lint --diff
# safe automatic cleanup
declarch lint --fix
# strict CI-like mode (warnings fail)
declarch lint --strict
# state structure repair only
declarch lint --repair-state
Helpful filters:
declarch lint --mode conflicts --backend aur
declarch lint --mode duplicates --backend flatpak
Info for debugging
Use info to explain state and scope:
# full tracked state
declarch info --list --scope all
# only unmanaged installed packages
declarch info --list --scope unmanaged
# backend focus
declarch info --list --scope all --backend soar
# package-focused status/reasoning
declarch info firefox
declarch info --package firefox
State mismatch (safe fix, no uninstall)
Use when sync shows unexpected Adopt, wrong backend mapping, or stale entries.
1) Preview
declarch lint --state-rm soar:firefox --dry-run
2) Remove from state
declarch lint --state-rm soar:firefox
3) Verify
declarch info --list --scope all --backend soar
declarch --dry-run sync
Common state remove patterns:
# exact id
declarch lint --state-rm backend:package
# plain name in one backend
declarch lint --state-rm package --state-rm-backend backend
# remove all entries for one backend
declarch lint --state-rm-backend backend --state-rm-all
Search debugging tips
# backend-specific search
declarch search soar:firefox
declarch search firefox --backends soar
# local installed scan only
declarch search firefox --local
# managed-only check (declarch state)
declarch search firefox --installed-only
Use --verbose when you need backend timing/error details.
Suggested workflow
declarch info --doctor
declarch lint --mode validate
declarch lint --diff
declarch --dry-run sync
If the plan still looks wrong, use targeted state cleanup (--state-rm*) and re-run dry-run sync.
Notes
--state-rm*only changes declarch state; it does not uninstall packages.- If package name is ambiguous across backends, use
backend:package. - Add
-yfor non-interactive runs.
Remote Init (Advanced)
Use this page when you want to initialize config from a remote source.
Supported source forms
user/repo
user/repo:variant
user/repo/branch
gitlab.com/user/repo
https://example.com/path/declarch.kdl
registry/module
Resolution behavior
GitHub shorthand
declarch init username/dotfiles
Resolves to repository default branch and fetches declarch.kdl.
Variant
declarch init username/dotfiles:minimal
Targets variant config (e.g. declarch-minimal.kdl).
Branch
declarch init username/dotfiles/develop
Fetches from explicit branch path.
GitLab
declarch init gitlab.com/username/dotfiles
Direct URL
declarch init https://example.com/config.kdl
Registry module
declarch init hyprland/niri-nico
Typical safe flow
declarch init username/dotfiles --dry-run
declarch init username/dotfiles
declarch lint --mode validate
declarch --dry-run sync
Operational flow
- Resolve source candidates.
- Download candidate content.
- Validate KDL parseability.
- Write to local config path.
- Initialize missing local structure if needed.
Safety recommendations
# inspect before writing local config
declarch init username/repo --dry-run
- treat remote config as untrusted input,
- review hooks and backend commands before full sync,
- prefer branch/tag pinning for reproducibility.
Failure modes
not found: wrong source path/variant/branch.parse error: remote file is not valid KDL.network error: transport or host availability issue.
Troubleshooting flow
declarch -v init username/repo
declarch lint --mode validate
Troubleshooting (Advanced)
Use this page when a command fails or behaves differently than expected. Start with simple checks first, then move to deeper checks.
Quick first checks
declarch lint --mode validate
declarch info --doctor
declarch --dry-run sync
1) Backend not found
Error pattern:
Backend 'xxx' not found
Actions:
declarch init --backend xxx
declarch lint --mode validate
Then confirm backend import in declarch.kdl under backends { ... }.
If you are not sure where your config lives on this OS, run:
declarch info --doctor
2) Missing backend binary
Error pattern:
Package manager error: yarn not found
Actions:
- install the binary, or
- stop using that backend for now, or
- set a compatible fallback backend (example:
nala -> apt).
Verify with:
declarch info yarn -v
3) Parse errors (KDL)
Error pattern includes line/column.
Actions:
- fix unbalanced braces
- check quote usage in strings
- verify backend command templates include required placeholders (
{packages},{query},{binary}when needed)
Validate quickly:
declarch lint --mode validate
4) Search timeout/slow backend
Actions:
# narrow scope
declarch search firefox -b flatpak --limit 10
# local-only mode
declarch search firefox --local
If this keeps happening, check backend search/search_local commands and avoid interactive prompts.
5) Sync appears to do nothing
This is often normal: desired state already matches installed state.
Inspect drift/orphans:
declarch info --list --scope orphans
6) Permissions / sudo
If backend requires root, ensure backend is configured correctly (needs_sudo) and your environment can prompt or run privileged commands.
Linux path permission check example:
mkdir -p ~/.config/declarch
chmod 755 ~/.config/declarch
On macOS/Windows, use:
declarch info --doctor
7) State reset procedure
If state is corrupted or stale, reset and re-check:
rm ~/.local/state/declarch/state.json
declarch init
declarch --dry-run sync
For non-Linux paths, first find your real state path with:
declarch info --doctor
8) Debug bundle
Before opening an issue, collect this output:
declarch -v lint --mode validate
declarch -v info --doctor
declarch -v --dry-run sync
Issue tracker:
- https://github.com/nixval/declarch/issues
Version Pinning (Planned)
Version pinning is not active yet.
Current direction:
- backend-capability based (not every package manager supports strict pinning)
- opt-in per package/backend
- clear handling for unsupported pin requests (
warnorerror) - backward-compatible config/state evolution
When implemented, this page will include:
- supported backends/capability matrix
- syntax examples
- migration notes
Policy, Hooks, and Editor Behavior (Advanced)
This page documents runtime behavior that often impacts safety and automation.
1) Policy block: what it controls
Example:
policy {
protected "linux" "systemd"
orphans "ask"
require_backend "true"
forbid_hooks "false"
on_duplicate "warn"
on_conflict "warn"
}
Meaning (practical):
protected: package names that should not be removed by prune-style flows.orphans: orphan handling strategy (keep,remove,askdepending on backend flow).require_backend: force explicit backend declaration; avoid implicit backend behavior.forbid_hooks: hard block hook execution even when CLI uses--hooks.on_duplicate: duplicate declaration policy (warnorerror).on_conflict: cross-backend conflict policy (warnorerror).
Related checks:
declarch lint --mode validate
declarch lint --mode duplicates
declarch lint --mode conflicts
2) Hooks execution policy (safety gate)
Hooks are intentionally gated by multiple conditions.
Required conditions to execute hooks
- Hooks exist in config.
- Config explicitly enables hooks:
experimental {
"enable-hooks"
}
- CLI call includes
--hooks. policy.forbid_hooksis not blocking hooks.
If one condition is missing, hooks are skipped/blocked.
Hook phases
Supported lifecycle phases include:
pre-sync,post-syncon-success,on-failurepre-install,post-installpre-remove,post-removeon-update
Hook command safety rules
Hook command validation rejects risky patterns, including:
- embedded
sudoin command string - path traversal patterns like
../ - unsafe characters outside allowed safe set
Runtime details:
- hook timeout is enforced
- behavior on failure depends on hook error policy (
warn,required,ignore)
3) Editor selection policy (declarch edit)
Current runtime priority (actual behavior):
editorvalue from root config (declarch.kdl)$VISUAL$EDITOR- fallback to
nano
If configured editor is missing in PATH, declarch warns and falls through to next option.
Useful edit flags:
declarch edit mymodule --preview --number
declarch edit mymodule --validate-only
declarch edit mymodule --auto-format
declarch edit mymodule --backup
4) Self-update ownership policy
self-update is intentionally constrained by install ownership.
If installation is owned by an external package manager (AUR/Homebrew/Scoop/Winget), declarch does not force direct overwrite and instead shows update hints for that package manager.
Use package-manager-native update command in those cases.
5) Recommended safe flow
declarch lint --mode validate
declarch lint --mode duplicates
declarch lint --mode conflicts
declarch --dry-run sync --hooks
declarch sync --hooks
If hooks are not expected to run, verify:
experimental { "enable-hooks" }--hooksis presentpolicy.forbid_hooksis not enabled
Integration Examples (API, MCP, Plugins)
This page shows practical integration patterns you can build around declarch. Core idea: keep declarch simple, extend behavior from outside.
Extension examples (external executables)
1) Security audit plugin
Command name example: declarch-ext-security-audit
- Reads package inventory from:
declarch info --list --format json --output-version v1
- Checks vulnerability/advisory sources.
- Outputs risk summary for CI.
2) Notification plugin
Command name example: declarch-ext-notify
- Runs after sync in CI/local automation.
- Sends concise report to Discord/Slack/Telegram.
- Useful for shared infra/team setups.
3) Team policy plugin
Command name example: declarch-ext-policy-team
- Rejects forbidden packages/backends before apply.
- Enforces naming/module conventions.
- Great for organization-wide baseline rules.
4) Export plugin
Command name example: declarch-ext-export
- Converts declarch managed state/plan into other formats:
- CSV/JSON inventory
- infra report artifacts
- dashboard feed input
Protocol reference:
docs/contracts/v1/extensions-protocol.md
MCP examples (good first step)
Read-only MCP tools are low-risk and high value.
Candidate MCP tools:
declarch_infodeclarch_lintdeclarch_searchdeclarch_sync_dry_run
These can call declarch and parse machine output (v1 envelope).
API examples (optional)
If needed later, an API can mirror existing command surfaces:
GET /infoGET /lintGET /search?q=...POST /sync/dry-run
Keep API responses aligned with the same v1 envelope contract.
Integrations in CI/CD
- PR validation:
declarch lint --strictdeclarch --dry-run sync
- Artifact export:
- store
info/listmachine output as CI artifacts.
- store
- Team notifications:
- send drift warnings or preview summaries.
Suggested rollout order
- Stabilize machine output contracts (
v1). - Build read-only MCP adapter externally.
- Add extension discovery/runtime (
declarch ext) incrementally. - Re-evaluate embedded API only when real usage needs it.
MCP Setup (Technical)
This page shows how to connect declarch with MCP clients while keeping core behavior agnostic and safe.
Scope
- MCP adapter is external (
declarch-mcp), not in-process plugin code. - Core
declarchlogic is unchanged. - Read-only tools are available by default.
- Write/apply action is blocked by default and requires explicit opt-in.
declarch-mcpis a local stdio adapter.- declarch does not ship a built-in public HTTP MCP server in this guide.
Important: MCP config format is client-specific
MCP protocol standardizes message transport (JSON-RPC over stdio/http), not one universal
mcpServers file schema for every app.
So:
command + args + envpattern is common.- exact file path and key names depend on each client.
- your client config may look different and still be valid.
Why some examples are only command
For local stdio MCP, many clients can start a server process with just:
command: executable name/path
So this is valid when declarch-mcp is already in PATH:
{
"mcpServers": {
"declarch": {
"command": "declarch-mcp"
}
}
}
Add other fields only when needed:
args: if your server needs startup argumentsenv: if you need custom environment variablestype,url,headers: for remote HTTP/SSE servers
Important:
- If you only use local stdio,
command(and optionalargs/env) is enough. url/headersare only for clients that connect to remote HTTP MCP servers.
Safety model (default read-only)
By default, MCP write actions are disabled.
To allow a write tool, enable it explicitly in declarch.kdl:
mcp {
mode "write-enabled"
allow_tools "declarch_sync_apply"
}
Without this block, write calls are rejected even if client sends them.
Common fields across clients (quick map)
- Local stdio (process on your machine):
- usually
command - optional
args,env - some clients also accept/require
type: "stdio"ortype: "local"
- usually
- Remote MCP over network:
- usually
url(orhttpUrl/serverUrldepending client) - optional/required
type(http,streamableHttp,sse) - optional
headersfor auth
- usually
Recommended standard environment
Start from normal declarch setup:
declarch init
Linux defaults are usually:
- config:
~/.config/declarch - state:
~/.local/state/declarch
Use this to confirm your actual paths:
declarch info --doctor
Binary requirement
Your MCP client must be able to run declarch-mcp.
- If installed in PATH: use
command = "declarch-mcp"(or JSON equivalent). - If not in PATH: set
commandto the full binary path.
DECLARCH_BIN is optional and only needed when you want to force a specific declarch binary.
Tools exposed
declarch_infodeclarch_listdeclarch_lintdeclarch_searchdeclarch_sync_dry_rundeclarch_sync_apply(only listed when config allows it)
Quick copy: generic local MCP config
Use this template and adapt keys to your client schema:
{
"mcpServers": {
"declarch": {
"command": "declarch-mcp"
}
}
}
That is enough for standard usage.
declarch will use normal OS default paths automatically.
If declarch-mcp is not in PATH yet, set command to the full binary path.
Quick copy: Codex (~/.codex/config.toml)
[mcp_servers.declarch]
command = "declarch-mcp"
args = []
Optional only if you want to force a specific declarch binary:
[mcp_servers.declarch.env]
DECLARCH_BIN = "/path/to/declarch"
Optional guarded apply:
[mcp_servers.declarch.env]
DECLARCH_MCP_ALLOW_APPLY = "1"
Quick copy: Gemini (~/.gemini/antigravity/mcp_config.json)
{
"mcpServers": {
"declarch": {
"command": "declarch-mcp",
"args": []
}
}
}
Optional:
{
"mcpServers": {
"declarch": {
"command": "declarch-mcp",
"env": {
"DECLARCH_BIN": "/path/to/declarch"
}
}
}
}
Quick copy: Qwen (~/.qwen/settings.json)
Some Qwen setups accept command + args directly.
If env fields are not supported in your version, use a shell wrapper:
{
"mcpServers": {
"declarch": {
"command": "bash",
"args": [
"-lc",
"declarch-mcp"
]
}
}
}
Enable guarded apply in Qwen wrapper command by adding:
DECLARCH_MCP_ALLOW_APPLY=1
inside the same bash -lc command string.
Quick copy: Claude Code
Claude setup can vary by app version and integration mode.
If your config file does not expose a direct mcpServers block, use Claude's MCP config location
for your version and map the same payload below.
Use your Claude MCP server config location/schema, then map it to the same payload:
- command:
.../declarch-mcp - optional env:
DECLARCH_BIN(only when needed) - optional env:
DECLARCH_MCP_ALLOW_APPLY=1(only when you want write/apply)
Quick copy: enable guarded apply
If you explicitly want AI to run declarch sync apply:
{
"mcpServers": {
"declarch": {
"command": "declarch-mcp",
"env": {
"DECLARCH_MCP_ALLOW_APPLY": "1"
}
}
}
}
Also add config consent in declarch.kdl:
mcp {
mode "write-enabled"
allow_tools "declarch_sync_apply"
}
And MCP call must include:
{
"name": "declarch_sync_apply",
"arguments": {
"confirm": "APPLY_SYNC"
}
}
Without config consent + env guard + confirm token, apply is rejected.
Client notes
- Different clients use different config file paths/field names.
- Keep the same command/env payload, then adapt to each client’s schema.
- Start with read-only tools first, then enable apply only when needed.
- Do not commit real API keys/tokens from client config files.
- When a client supports both local and remote MCP, start with local stdio first.
Optional: custom XDG (advanced)
Custom XDG is optional and usually only needed for isolated test setups.
Cross-Distro Support
Declarch is distro-agnostic. Real behavior depends on which backend binaries and backend configs are available.
How to think about it
- Declarch = coordinator.
- Backends = actual package-manager commands.
- You can mix distro/system + language backends in one file.
Common backend groups
- Arch-oriented:
aur,pacman - Debian/Ubuntu:
apt,nala - Fedora/RHEL:
dnf - Universal:
flatpak,snap,nix,soar - Language/dev:
npm,pnpm,yarn,bun,cargo,pip,gem,go
Starter commands
Arch-based
declarch init
declarch init --backend paru,yay
Debian/Ubuntu
declarch init
declarch init --backend apt,nala,npm,cargo
Fedora
declarch init
declarch init --backend dnf,flatpak,npm,cargo
Fallback examples
nala -> aptyay -> pacmanbun -> npmaur -> paru -> yay -> pacman
Fallback keeps workflows usable when preferred binary is missing.
Improve support
Contribute backend definitions and fixes:
- https://github.com/nixval/declarch-packages