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

nor-cli

v0.71.0

Published

Organise packages and reproducible workstation state

Downloads

1,007

Readme

NOR - Organize Repos

A unified Linux CLI for managing packages, systemd units, editor extensions, dotfiles, and reproducible workstation state across multiple package managers.

What This Solves

Modern Linux workstations often end up spread across multiple package and configuration systems: DNF packages, Homebrew tools, Flatpak apps, global pnpm packages, editor extensions, dotfiles, and sometimes Arch/AUR packages through a container. Keeping that setup updated, searchable, and reproducible usually means remembering many different commands and manually tracking what is installed where.

nor turns that scattered environment into a single managed package stack. It provides one CLI for syncing updates, searching across supported repositories, saving package inventories, and restoring a workstation later. This makes it easier to rebuild a machine, migrate to a new laptop, recover after a reinstall, or simply keep a daily Linux setup consistent.

This project came from trying different Linux distributions, including NixOS, and wanting the reproducibility benefits without adopting the full Nix workflow. nor keeps the familiar package managers and habits of standard Linux distributions while adding a practical restore path for the tools, apps, extensions, dotfiles, and custom installs that make up a real workstation.

Installation

Homebrew

Homebrew needs a working system C compiler and the standard development tools when it builds formulae without bottles.

Fedora:

sudo dnf group install development-tools
sudo dnf install procps-ng curl file

Debian or Ubuntu:

sudo apt-get install build-essential procps curl file git
brew tap yunieralvarez/tap https://gitlab.com/yunieralvarez/nor.git
brew install nor

The formula installs the nor command into Homebrew's bin directory and builds the CLI from the tagged release source.

Arch Linux

Build and install the tracked PKGBUILD:

git clone https://gitlab.com/yunieralvarez/nor.git
cd nor
makepkg -si

The package installs nor under /usr/lib/nor and links the command into /usr/bin.

npm

Install the public npm package globally:

npm install --global nor-cli

The package name is nor-cli, but the installed command is nor.

To update:

brew update
brew upgrade nor

For Arch packages built directly from the PKGBUILD, pull the latest release and run makepkg -si again.

For npm:

npm update --global nor-cli

Uninstall

brew uninstall nor

Arch Linux:

sudo pacman -Rns nor

npm:

npm uninstall --global nor-cli

Custom packages installed from recipes are left under ~/.nor/out.

Features

  • Unified interface for Pacman/AUR, DNF, Homebrew, Nix, Flatpak, npm, pnpm, .NET global tools, VS Code extensions, VSCodium extensions, Archbox (Arch via Distrobox), systemd, ZVM, YADM, and custom recipes
  • nor sync - update everything with one command
  • nor search <name> - search all supported package repositories simultaneously
  • Per-manager restore commands - restore saved package and extension lists
  • State tracking - package inventories persisted to ~/.local/state/nor/state.json

Requirements

  • Node.js
  • Homebrew, makepkg, or npm for the supported installation methods

The Homebrew formula and Arch package install Node.js automatically. Linux systems still need the build tools listed above when Homebrew builds nor from source. Individual nor subcommands require their underlying tools when enabled, such as pacman, dnf, brew, nix, flatpak, npm, pnpm, dotnet, systemctl, code, codium, yadm, zvm, distrobox, or archbox.

Usage

After installing, run commands with nor:

nor sync
nor search ripgrep
nor dotnet install dotnet-ef
nor code install esbenp.prettier-vscode
nor codium install jnoortheen.nix-ide

For local development, install dependencies and run commands through pnpm start:

pnpm install
pnpm start [command] [options]
pnpm start sync
pnpm start search ripgrep
pnpm start dotnet install dotnet-ef
pnpm start code install esbenp.prettier-vscode
pnpm start codium install jnoortheen.nix-ide

Global commands

| Command | Description | | ------------------- | -------------------------------------- | | nor sync | Sync all package managers | | nor search <name> | Search across enabled package managers | | nor restore | Run the aggregate restore workflow |

Pacman

Native Arch Linux repository and AUR package management. The configured command backend can use Pacman, aurutils, or an AUR helper.

| Command | Description | | -------------------------------- | ------------------------------------------- | | nor pacman sync | Update packages, autoremove, and save state | | nor pacman install <names...> | Install packages | | nor pacman update [names...] | Update all or selected packages | | nor pacman downgrade <names> | Install a cached older package version | | nor pacman remove <names...> | Remove packages | | nor pacman auto-remove | Remove unused dependencies | | nor pacman search <name> | Search packages | | nor pacman info <name> | Show package details | | nor pacman ignore <names...> | Exclude packages from managed updates | | nor pacman unignore <names...> | Stop excluding packages | | nor pacman watch <names...> | Track uninstalled packages in saved state | | nor pacman unwatch <names...> | Stop tracking uninstalled packages | | nor pacman restore | Restore saved explicitly installed packages |

DNF

Fedora system packages and package groups.

| Command | Description | | ---------------------------------- | ---------------------------------------- | | nor dnf sync | Upgrade packages, autoremove, save state | | nor dnf install <names...> | Install packages | | nor dnf update | Upgrade packages | | nor dnf remove <names...> | Remove packages | | nor dnf group-install <names...> | Install package groups | | nor dnf group-remove <names...> | Remove package groups | | nor dnf auto-remove | Remove unused dependencies | | nor dnf search <name> | Search packages | | nor dnf info <name> | Show package details | | nor dnf restore | Restore saved packages and groups |

Homebrew

Formulae, casks, and taps.

| Command | Description | | ------------------------------------ | --------------------------------------- | | nor brew sync | Update, upgrade, and save state | | nor brew install <names...> | Install formulae | | nor brew install --cask <names...> | Install casks | | nor brew tap <name> | Add a tap | | nor brew untap <name> | Remove a tap | | nor brew update | Update and upgrade packages | | nor brew remove <names...> | Uninstall packages | | nor brew search <name> | Search packages | | nor brew info <name> | Show package details | | nor brew restore | Restore saved taps, formulae, and casks |

Archbox

Arch Linux packages through the archbox Distrobox container and the configured AUR helper.

| Command | Description | | --------------------------------------------- | --------------------------------------------- | | nor archbox sync | Ensure Archbox exists, update, and save state | | nor archbox install <names...> | Install packages | | nor archbox update | Update packages | | nor archbox remove <names...> | Remove packages | | nor archbox search <names...> | Search packages | | nor archbox info <names...> | Show package details | | nor archbox export-apps <names...> | Export desktop apps from Archbox | | nor archbox export-apps --delete <names...> | Delete exported desktop apps | | nor archbox export-bins <names...> | Export binaries from Archbox | | nor archbox export-bins --delete <names...> | Delete exported binaries | | nor archbox restore | Restore packages and exports |

Flatpak

Flatpak applications and runtimes.

| Command | Description | | ----------------------------------------- | ---------------------------------------------- | | nor flatpak sync | Update, remove unused runtimes, and save state | | nor flatpak install <remote> <names...> | Install apps from a remote | | nor flatpak update | Update apps and remove unused runtimes | | nor flatpak remove <names...> | Remove apps | | nor flatpak search <name> | Search apps | | nor flatpak restore | Restore saved apps by remote |

pnpm

Global pnpm packages.

| Command | Description | | ----------------------------- | ------------------------------------- | | nor pnpm sync | Update global packages and save state | | nor pnpm install <names...> | Install global packages | | nor pnpm update | Update global packages | | nor pnpm remove <names...> | Remove global packages | | nor pnpm restore | Restore saved global packages |

npm

Global npm packages.

| Command | Description | | ---------------------------- | ------------------------------------- | | nor npm sync | Update global packages and save state | | nor npm install <names...> | Install global packages | | nor npm update | Update global packages | | nor npm remove <names...> | Remove global packages | | nor npm restore | Restore saved global packages |

Nix

Packages installed in the current Nix profile.

| Command | Description | | ---------------------------- | ------------------------------------------------ | | nor nix sync | Clean profile history and save state | | nor nix install <names...> | Add packages from nixpkgs | | nor nix update | Upgrade all profile packages | | nor nix remove <names...> | Remove packages from the profile | | nor nix search <name> | Search nixpkgs | | nor nix gc | Clean profile history and run garbage collection | | nor nix restore | Restore saved profile packages |

Dotnet

.NET global tools. This command only runs when dotnet.enabled is enabled in config.json and requires the dotnet CLI.

| Command | Description | | ------------------------------- | ---------------------------------- | | nor dotnet sync | Update global tools and save state | | nor dotnet install <names...> | Install global tools | | nor dotnet update | Update global tools | | nor dotnet remove <names...> | Uninstall global tools | | nor dotnet restore | Restore saved global tools |

VS Code and VSCodium

Extension management is available for both editor commands:

  • nor code ... uses the code CLI.
  • nor codium ... uses the codium CLI.

| Command | Description | | ------------------------------- | ----------------------------------------- | | nor code sync | Update VS Code extensions and save state | | nor code install <names...> | Install VS Code extensions | | nor code update | Update VS Code extensions | | nor code remove <names...> | Remove VS Code extensions | | nor code restore | Restore saved VS Code extensions | | nor codium sync | Update VSCodium extensions and save state | | nor codium install <names...> | Install VSCodium extensions | | nor codium update | Update VSCodium extensions | | nor codium remove <names...> | Remove VSCodium extensions | | nor codium restore | Restore saved VSCodium extensions |

Custom

Custom package flows provided as TypeScript recipes in ~/.config/nor/custom. Each file name is the custom package name, such as ~/.config/nor/custom/blender.ts, and is also the Arch/AUR package name used for version lookup.

Recipes export only normalizeVersion and install. Each function receives ctx, which includes ctx.version, ctx.sh, ctx.dirs, and small helpers for downloading and extracting archives. normalizeVersion receives the raw package version in ctx.version; install receives the normalized version.

Recipe installs use ctx.dirs.install, which resolves to ~/.nor/out/<name>. Custom packages also create command symlinks in ~/.nor/bin; add that directory to your PATH if you want to run custom package binaries from a shell. The symlink name defaults to the basename of the returned bin path, or recipes may return optional binName to choose a custom command name. Recipes may return optional desktop metadata to create a desktop launcher. Removal is handled by nor and cleans the download directory, install directory, bin links, and desktop launcher.

| Command | Description | | ------------------------------- | -------------------------------------- | | nor custom sync | Update tracked custom packages | | nor custom install <names...> | Install custom packages by recipe name | | nor custom update | Update tracked custom packages | | nor custom remove <names...> | Remove installed custom packages | | nor custom restore | Install all custom recipes |

Example ~/.config/nor/custom/blender.ts recipe:

import type { Custom } from '../types';

export default {
  normalizeVersion(ctx) {
    // Arch reports Blender versions with an epoch prefix, such as 17:4.4.3-1.
    return ctx.version.split(':')[1]!.split('-')[0]!;
  },

  async install(ctx) {
    // Blender hosts downloads under a major.minor release directory.
    const release = ctx.version.split('.').slice(0, -1).join('.');

    const archive = await ctx.download(
      `https://download.blender.org/release/Blender${release}/blender-${ctx.version}-linux-x64.tar.xz`,
    );

    const dir = await ctx.extract(archive);
    const icon = `${ctx.dirs.icons}/blender.svg`;
    // Reuse the icon bundled in the extracted Blender archive.
    ctx.sh.exec('cp', [`${dir}/blender.svg`, icon]);

    return {
      bin: `${dir}/blender-launcher`,
      icon,
      desktop: {
        categories: ['Graphics', '3DGraphics'],
        comment: 'Blender 3D Creation Suite',
        name: 'Blender',
      },
    };
  },
} satisfies Custom;

Example ~/.config/nor/custom/godot.ts recipe:

import type { Custom } from '../types';

export default {
  normalizeVersion(ctx) {
    // Strip the package release suffix from versions such as 4.4.1-1.
    return ctx.version.split('-')[0]!;
  },

  async install(ctx) {
    const archive = await ctx.download(
      `https://downloads.godotengine.org/?version=${ctx.version}&flavor=stable&slug=mono_linux_x86_64.zip&platform=linux.64`,
      // Godot serves this URL through a redirect with the real filename in headers.
      { contentDisposition: true },
    );

    const dir = await ctx.extract(archive);

    // Godot's release archive does not include a desktop icon in the needed path.
    const icon = await ctx.downloadIcon(
      'https://godotengine.org/assets/press/icon_color.svg',
    );

    return {
      bin: `${dir}/Godot_v${ctx.version}-stable_mono_linux.x86_64`,
      binName: 'godot',
      icon,
      desktop: {
        categories: ['Development', 'IDE'],
        comment: 'Godot Game Engine',
        name: 'Godot',
      },
    };
  },
} satisfies Custom;

The installer writes the helper type file to ~/.config/nor/types.ts. The import is optional at runtime, but useful for editor checking.

nor custom sync also runs an optional user sync hook at ~/.config/nor/sync.ts before updating tracked custom packages:

export default async ({ sh }) => {
  sh.exec('example-command', ['--flag']);
};

ZVM

Zig Version Manager.

| Command | Description | | ---------------- | ----------- | | nor zvm sync | Upgrade ZVM | | nor zvm update | Upgrade ZVM |

YADM

Dotfile sync. This command only runs when yadm.enabled is enabled in config.json.

| Command | Description | | --------------- | ----------------------------------------- | | nor yadm sync | Sync configured dotfiles and push changes |

systemd

Enabled system and user services, sockets, and timers.

| Command | Description | | ------------------------------------- | ----------------------------- | | nor systemd sync | Save enabled units | | nor systemd enable <names...> | Enable and start system units | | nor systemd enable-user <names...> | Enable and start user units | | nor systemd disable <names...> | Disable and stop system units | | nor systemd disable-user <names...> | Disable and stop user units | | nor systemd restore | Restore saved enabled units |

State

Use nor state --all to print all saved state, or nor state <manager> [query] to inspect one manager and optionally filter its entries.

Configuration

File: ~/.config/nor/config.json

{
  "archbox": {
    "aur": { "helper": null },
    "enabled": false,
    "name": "archbox",
    "state": { "ignore": { "packages": [] } }
  },
  "brew": { "enabled": false },
  "code": { "enabled": false },
  "codium": { "enabled": false },
  "dnf": {
    "enabled": false,
    "refresh": false,
    "state": { "ignore": { "groups": [], "packages": [] } }
  },
  "dotnet": { "enabled": false },
  "flatpak": { "enabled": false },
  "nix": {
    "allowUnfree": false,
    "enabled": false,
    "store": { "historyRetention": "" }
  },
  "npm": { "enabled": false },
  "pacman": {
    "commands": {
      "info": "pacman",
      "install": { "backend": "package", "fallback": null, "retry": false },
      "search": "pacman",
      "update": "pacman"
    },
    "enabled": false,
    "aurUtils": {
      "cleanAfterUpdate": false,
      "keepVersions": 1,
      "repoDir": null,
      "repoName": null
    }
  },
  "pnpm": { "enabled": false },
  "systemd": { "enabled": false },
  "yadm": { "enabled": false },
  "zvm": { "enabled": false }
}

Development Commands

pnpm fmt          # Format source code with Prettier
pnpm start        # Run the CLI from TypeScript
pnpm build        # Build dist/main.js
scripts/release.sh # Publish a release to Git, Homebrew, Arch, and npm

License

MIT