Skip to content

CLI

The sysdef CLI is built using Commander.js and provides a simple interface for managing your system configuration. The main entry point is through the sysdef command located in your bin/ directory.

Sysdef uses a root directory (defaults to $HOME/sysdef or can be set via SYSDEF_ROOT_DIR environment variable) that contains:

  • Directorybin/
    • bun
    • sysdef
  • Directorysysdef-src/
    • *.ts (source files)
  • Directorymodules/
    • *.ts (module definitions)
  • Directoryproviders/
    • *.ts (provider definitions)
  • config.yaml
  • sysdef-lock.json (auto-generated)
  • sysdef-track.json (auto-generated)

Running sysdef without arguments displays help information for all available commands.

The primary command for synchronizing your system configuration. This command:

  1. Syncs files: Creates symlinks and generates files from your modules
  2. Manages packages: Installs/removes packages through configured providers
  3. Runs events: Executes any onEverySync functions in your modules
  4. Updates lockfile: Records exact package versions for reproducibility

Options:

  • -d, --dry-run: Preview changes without executing them
  • -s, --safe: Install packages but don’t remove any (safer for testing)
  • -f, --files-only: Only sync files, skip package management
  • -h, --help: Show help for this command

Examples:

Terminal window
# Normal sync
sysdef sync
# Preview what would happen
sysdef sync --dry-run
# Only sync files, don't touch packages
sysdef sync --files-only
# Sync but don't remove any packages
sysdef sync --safe

Updates managed packages to their newest available versions and refreshes the lockfile. With no arguments it updates every package for every configured provider; pass a provider (and optionally specific package names) to narrow it.

Examples:

Terminal window
# Update everything
sysdef update
# Update all packages for one provider
sysdef update npm
# Update specific packages
sysdef update npm typescript left-pad

Snapshots the versions currently installed on your system into sysdef-lock.json without installing, removing, or changing anything. This is bookkeeping-only: it re-pins each managed package to the version that’s actually present.

Use it when packages changed out-of-band (for example, you upgraded something with your package manager directly) and you want the lockfile to reflect reality without running a full sync.

Terminal window
sysdef update-lockfile

Manages which installed-but-unmanaged packages sysdef warns about. During sync, system providers (arch-official, apt, dnf) report every package on the machine through getInstalled(), so sysdef prints a warning listing packages that are installed but not declared in any module (it never removes these — sysdef only removes packages it installed itself and recorded in the lockfile). The trackfile (sysdef-track.json) lets you silence that warning for packages you don’t intend to manage. It is stored separately from the lockfile because it varies per machine (keep the lockfile committed, the trackfile gitignored).

Running sysdef track with no subcommand prints help. Subcommands:

  • sysdef track ignore <provider> [packages...] — mark specific packages untracked so sync stops warning about them.
  • sysdef track ignore-all [provider] — mark every currently installed-but-unmanaged package untracked (for one provider, or all if omitted). Handy for the first sync on an existing system.
  • sysdef track unignore <provider> [packages...] — remove packages from the untracked list, re-enabling the warning.
  • sysdef track list [provider] — show which packages are currently marked untracked.

Note: adding a package to a module (so it becomes managed) automatically drops it from the untracked list on the next sync.

Terminal window
# Stop warning about base-system packages you'll never manage with sysdef
sysdef track ignore-all arch-official
# Silence just a couple of packages
sysdef track ignore apt vim curl
# See what's currently ignored
sysdef track list

Lists all configured providers and checks their installation status. Each provider can define a checkInstallation() function to verify it’s working correctly.

Example output:

arch-official is installed correctly
apt is installed correctly
bun failed when checking its own installation: command not found

Shows all packages currently installed through sysdef providers.

Arguments:

  • provider (optional): Filter by specific provider name

Examples:

Terminal window
# List packages from all providers
sysdef list-installed
# List only packages from the arch-official provider
sysdef list-installed arch-official

Example output:

Currently installed packages for arch-official:
firefox@latest
git@2.42.0
neovim@0.9.4
Currently installed packages for bun:
typescript@5.2.2
@types/node@20.8.0

A simple test command that prints “Hello, world!” - useful for verifying the CLI is working.

The CLI uses the errorOut() function from sysdef.ts:9 for fatal errors, which prints an error message and exits with code 1. Common error scenarios:

  • Missing configuration file
  • Invalid module or provider files
  • Provider installation check failures
  • Package version conflicts between modules

The CLI loads configuration from:

  1. config.yaml: Main configuration specifying which modules and providers to load
  2. Module files: TypeScript files in the modules/ directory
  3. Provider files: TypeScript files in the providers/ directory
  4. Variables file: Optional variables.{ts,js,tsx,jsx} for global variables
  5. Lockfile: sysdef-lock.json for tracking exact package versions
  6. Trackfile: sysdef-track.json for packages you’ve marked untracked (see sysdef track)

All TypeScript/JavaScript files are dynamically imported and must export a default function that returns the appropriate object (Module, Provider, or variables record).