A yay-like AUR helper backed by the github.com/archlinux/aur mirror — no dependency on the aurweb RPC.
aur.archlinux.org has spotty uptime; the GitHub mirror is a single ~2 GiB monorepo with one branch per package. aurox clones it once, builds a zero-copy index from every .SRCINFO, and uses that for search, info, and dependency resolution. Refreshes are incremental fetches.
More demos: one-shot AUR install · repo install · system upgrade
Early — works end-to-end: AUR search/info/install (-S), recursive dep resolution, PKGBUILD review, and an interactive shell (aurox with no args) for staging + upgrading + applying. Repo/system upgrades go through pacman (-Syu is a passthrough). Expect rough edges.
Packaged as aurox:
git clone https://aur.archlinux.org/aurox.git
cd aurox
makepkg -si
# or with any AUR helper: yay -S auroxOnce installed, aurox can upgrade itself like any other AUR package.
Requires pacman, git, base-devel, pkgconf, rustup:
git clone https://github.com/nikicat/aurox
cd aurox
cargo install --path . --lockedaurox depends on a git revision of gitoxide
(for perf/instrumentation patches not yet in a published gix release). The
checked-in .cargo/config.toml sets net.git-fetch-with-cli = true so cargo
fetches it with the system git. If you build outside the source tree and your
git defaults to the reftable ref format, cargo's libgit2 backend can't read
the cached clone and fails with unknown refstorage format 'unknown'
(rust-lang/cargo#15184); the
same git-fetch-with-cli setting in your ~/.cargo/config.toml fixes it.
aurox mirrors the whole AUR as one git repo: a one-time ~2 GiB download
(~2.5 GiB on disk, ~10 min); afterwards refreshes are small incremental
fetches. Nothing downloads without a yes — the shell asks a three-way question
at first launch (sync now / no, pacman-only from now on / later,
this session), aurox -Sy announces the cost and confirms, and
aurox -S <aur-pkg> without the mirror offers to set it up on the spot.
Until the mirror exists — or permanently, with aur = false in config.toml —
everything degrades to the official repos: search/info show repo results,
upgrades are repo-only, and unknown install targets say how to enable the AUR.
aurox accepts pacman's flag syntax. Operations it doesn't own (-Q, -R, -T, -D, -F, -U, and -Su system upgrades) are forwarded to pacman unchanged, so you can use it as a drop-in replacement.
| Command | What it does |
|---|---|
aurox |
Open the interactive shell (search · stage · upgrade · do) |
aurox -S <pkg>... |
Install AUR packages (recursive deps, batched sudo) |
aurox -Sy |
Incremental fetch of the AUR mirror (first run: asks, then clones) |
aurox -Syy |
Force a full re-clone (~10 min; asks first) |
aurox -Syu |
Forwarded to pacman -Syu — AUR upgrades live in the shell's upgrade |
aurox -Ss <regex> |
Search repos + AUR by name / desc / provides |
aurox -Si <pkg> |
Show package info (repos + AUR; repo wins a shared name) |
aurox -Sc / -Scc |
Remove built worktrees + pass -Sc/-Scc through to pacman |
aurox -G <pkg>... |
Clone a pkgbase into ./<pkgbase> from the local mirror (no network), origin set to the AUR's pushable SSH URL |
aurox -Gp <pkg> |
Print a pkgbase's PKGBUILD to stdout |
aurox -Rns <pkg> |
Forwarded to pacman unchanged |
AUR upgrades are an interactive flow now: run aurox (no args) to open the shell, then upgrade to stage the available AUR + repo upgrades, review/approve the AUR ones, and do. The explicit -Syu flag is a plain pacman -Syu passthrough.
Global flags: --devel (include -git/-svn/-hg/-bzr when the shell's upgrade computes candidates), --noconfirm, --asdeps, --color {auto,always,never}.
aurox -S yay-bin
aurox --devel # open the shell; `upgrade` then includes -git/-svn pkgs
aurox -Ss '^claude-'
aurox -Rns aurox # forwarded to pacman
RUST_LOG=aurox=debug aurox -SyOptional ~/.config/aurox/config.toml. All fields default to sensible values:
aur = true # false = pacman-only mode: no mirror, no prompts
mirror_url = "https://github.com/archlinux/aur.git"
build_dir = "~/.local/state/aurox/pkgs"
index_threads = 4
refresh_max_age_secs = 3600
color = "auto"
banner = true # ASCII-art splash when the shell starts
makepkg_path = "makepkg"
makepkg_args = ["-s", "--noconfirm", "--needed"]
privilege_escalator = "sudo" # or "doas" / "run0"
devel = false
aur_approval = "review" # or "auto" — auto stages AUR pkgs pre-approvedThe shell's approval gate: review (default) makes every staged AUR package
need review/approve before do runs it; auto stages them pre-approved.
(The pre-aur_approval review_default knob is gone; review_default = "skip" is now aur_approval = "auto".)
aur = false opts out of the AUR half entirely (the shell's first-launch
question writes it for you if you answer "no"): search, info, install, and
upgrades run against the official repos only, and nothing ever asks about the
mirror. Delete the line and run refresh aur (or aurox -Sy) to opt back in.
~/.local/state/aurox/
├── aur/ bare clone of the AUR mirror (~2 GiB)
├── pkgs/<pkgbase>/ per-pkgbase git worktree + cached .pkg.tar.zst, kept until -Sc
├── index.bin rkyv-archived index, mmap'd at load (~60–80 MB)
├── logs/ per-run debug logs (aurox-*.log), last 10 runs kept
└── traces/ per-run Chrome/Perfetto span traces (aurox-*.json)
~/.config/aurox/config.toml optional
The logs/ files are always written at debug level regardless of console
verbosity. RUST_LOG (e.g. RUST_LOG=aurox=debug) raises only the console
tracing level — it does not change what lands in logs/.
The traces/ files drop straight into ui.perfetto.dev,
but the aurox-trace helper answers "where did the time in span X go?" from the
terminal without opening a browser. With no argument it reads the newest trace:
aurox-trace # spans aggregated by total self time
aurox-trace tree # full per-thread containment tree
aurox-trace tree --span receive # just the subtree(s) under `receive`
aurox-trace --min-ms 50 tree # hide spans shorter than 50 ms
self time is each span's wall time minus its children — the un-instrumented
cost that lives directly in that span. Pass --file <path> for a specific trace.
- No
aurwebRPC — all metadata comes from the GitHub mirror clone. - Incremental refresh —
git fetchreports changed refs; only those are re-indexed. - Zero-copy index —
index.binis arkyvarchive, mmap'd directly. - One sudo prompt per install — repo deps and built packages each go in as one batched pacman call. No keepalive loop.
- Idempotent builds — the artifact filename is the cache key, so a re-run after declining the install just replays the install step.
Each of these, with the tradeoffs and the yay/paru behaviour it's measured
against: docs/COMPARISON.md.
cargo fmt --all
cargo clippy --all-targets -- -D warnings
cargo testThe multi-process half — sudo gating, asdeps flips, build-failure isolation,
makepkg log capture — can only be tested against real pacman + makepkg, so
there is a black-box container suite alongside the Rust tests:
bash tests/container/run.sh # smoke tier (~30 s on 8 cores)
bash tests/container/run.sh --rebuild smoke # bust image cache after fixture changesBoth layers gate CI. docs/TESTING.md is the reference:
tiers, fixtures, PTY drivers, and the traps (that --rebuild above is the one
that bites everyone).
A .pre-commit-config.yaml is checked in to catch the cheap failures
(cargo fmt --check, taplo fmt --check, taplo lint) before they round-trip
through CI. One-time setup per clone:
cargo install prek # or: pacman -S prek (once it lands in extra)
prek installThe hook stays sub-second; cargo clippy and cargo test are deliberately
left out — run them yourself before pushing.
MIT.



