npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

hofi-cli

v0.1.4

Published

Readme

hofi

A declarative system configuration tool for Arch Linux. Define your packages, symlinks, mount drives, and default apps in TOML files — then apply them all with a single switch command.

Features

  • Package management — install/update pacman, AUR (paru), and Flatpak packages declaratively
  • Symlinks — create and manage symlinks between dotfiles, scripts, and config directories
  • MIME defaults — set default applications and file-type associations system-wide
  • Mount drives — configure systemd mount units with UUID, filesystem type, and options
  • Config includes — chain multiple TOML config files together
  • Dry-run mode — preview changes before applying anything
  • Validation — Zod schema validation + runtime checks (symlink targets, mount UUIDs, package existence)

Prerequisites

  • Bun runtime
  • Arch Linux (pacman-based)
  • paru (optional, for AUR packages)
  • Flatpak (optional, for Flatpak packages)

Install & Build

bun install                       # install dependencies
bun run build                     # bundle → dist/hofi.js
bun run compile                   # compile → ./bin/hofi (standalone binary)

Quick Start

# Scaffold a new config from your current system state
bun run index.ts init

# Validate the generated config
bun run index.ts validate

# Preview what would change
bun run index.ts switch --dry-run

# Apply the configuration
bun run index.ts switch

CLI Commands

| Command | Description | |---------|-------------| | scan | Detect and print system environment (OS, init, pkg managers, AUR helper, sudo status) | | init | Scaffold hofi/config.toml + hofi/mimeapps.toml by scanning current system packages and MIME associations | | validate [dir] | Parse and validate the TOML config at the given directory (defaults to cwd) | | switch [dir] | Diff config against current state, prompt to apply changes (packages, symlinks, mounts, defaults) | | switch [dir] --dry-run | Same as switch, but only shows the diff table without applying |

Run with --help for usage details:

bun run index.ts --help

Configuration Format

Config is TOML (config.toml). All sections are optional.

# ── User ──
[user]
name = "user"
homeDir = "/home/user"

# ── Packages ──
[packages]
pacman = ["base", "base-devel", "neovim", "git"]
aur = ["yay"]

[packages.flatpak]
user = ["com.discordapp.Discord"]
system = ["org.gimp.GIMP"]

# ── Default Applications ──
[defaults.apps]
browser = "firefox.desktop"
editor = "nvim.desktop"
video = "vlc.desktop"
image = "gimp.desktop"
audio = "spotify.desktop"

# ── MIME Associations ──
[defaults.mime.defaultApplications]
"text/html" = "firefox.desktop"

[defaults.mime.addedAssociations]
"image/png" = "gimp.desktop"

# ── Mount Drives (systemd units) ──
[mounts./mnt/data]
description = "Data drive"
uuid = "1234-5678-ABCD"
type = "ext4"
options = ["defaults", "noatime"]
wantedBy = "local-fs.target"

# ── Includes (chain other TOML files) ──
includes = ["./mimeapps.toml"]

# ── Symlinks ──
[symlink.dotfiles]
target = "/home/user/dotfiles/nvim"
link = "/home/user/.config/nvim"

[symlink.scripts]
target = "/home/user/scripts"
link = "/home/user/.local/bin"

Config Sections

| Section | Description | |---------|-------------| | [user] | User name and home directory | | [packages] | Lists of pacman, AUR, and Flatpak packages to install | | [defaults.apps] | Default application desktop entries for common categories | | [defaults.mime] | MIME type associations (defaultApplications and addedAssociations) | | [mounts.<point>] | Systemd mount unit definitions (UUID, filesystem type, options) | | includes | Array of paths to additional TOML config files (deep-merged, arrays overwritten) | | [symlink.<name>] | Symlink entries — each has a target (source) and link (destination) |

How switch Works

  1. Parse — reads and Zod-validates the TOML config
  2. Diff — compares config against a hofi-lock.json metadata file (previous state)
  3. Preview — prints a diff table of what changed
  4. Confirm — prompts for confirmation (y/n)
  5. Apply — installs/removes packages, creates symlinks, writes systemd mount units, and updates MIME defaults
  6. Save — writes new metadata to hofi-lock.json

Project Structure

├── index.ts                    # CLI entrypoint (cac)
├── src/
│   ├── commands/
│   │   ├── scan.ts             # System environment detection
│   │   ├── init.ts             # Project scaffolding
│   │   ├── validate.ts         # Config validation
│   │   └── switch/
│   │       ├── index.ts        # Switch orchestrator
│   │       ├── packages.ts     # Package install/remove
│   │       ├── links.ts        # Symlink management
│   │       ├── mountDrive.ts   # systemd mount units
│   │       └── defaults.ts     # MIME / default apps
│   ├── backend/
│   │   ├── pacman.ts           # Pacman backend
│   │   ├── aur.ts              # AUR (paru) backend
│   │   └── flatpak.ts          # Flatpak backend
│   ├── core/
│   │   └── config/
│   │       ├── schema.ts       # Zod config schema
│   │       ├── parser.ts       # TOML parsing
│   │       └── template.ts     # Config templates
│   └── utils/
│       ├── logger.ts           # chalk + ora + boxen logger
│       ├── spawn.ts            # Bun.spawn wrapper
│       ├── diff.ts             # Config diff logic
│       ├── validation.ts       # Runtime validation helpers
│       └── write.ts            # File writing utilities
└── tests/                      # Unit tests (bun test)

Development

bun install                     # install deps
bun run index.ts --help         # show CLI help
bun run index.ts scan           # detect system environment
bun run index.ts init           # scaffold hofi/config.toml + hofi/mimeapps.toml
bun run index.ts validate       # validate TOML config in cwd
bun run index.ts switch <dir> --dry-run   # preview changes
bun run index.ts switch <dir>   # apply config to system
bun test                        # run unit tests (65+ tests)

License

MIT