Skip to content

Overview

The system supports multiple installation methods to accommodate different tool distribution patterns. Each method has its own parameters and use cases.

Direct download methods like github-release, curl-tar, or curl-binary are strongly recommended when available. Because they fetch isolated binaries directly into the dotfiles data directory, the dotfiles manager maintains full control over the runtime environment, version tracking, and execution shims.

Using external package managers like brew or npm is fully supported and sometimes necessary, but introduces potential state drift. These package managers natively own their own placement, upgrades, and environment links. If you run brew upgrade externally, the binary may update out of sync with what the dotfiles manager recorded. While this won’t break the system, it’s best practice to drive all updates through the dotfiles update CLI directly to keep state consistent.

MethodBest ForProsCons
aptDebian-family Linux packagesUses distro packagesLinux distro-specific, external state
brewmacOS/Linux toolsSimple, well-maintainedPlatform-specific, requires Homebrew
cargoRust toolsFast pre-compiled binariesRust tools only
dnfRPM-family Linux packagesUses distro packagesLinux distro-specific, external state
curl-binaryDirect binary downloadsSimplest, no extraction neededManual URL management
curl-scriptCustom installersFlexible, handles complex setupsLess predictable, security concerns
curl-tarArchive downloadsSimple, no dependenciesManual URL management
dmgmacOS .app bundlesHandles mount/unmount, archive extractmacOS only
pkgmacOS installer packagesUses native installer flowmacOS only
pacmanArch-family Linux packagesUses distro packagesLinux distro-specific, external state
gitea-releaseCodeberg / self-hosted Gitea toolsSupports any Gitea-compatible hostRequires instance URL
github-releaseMost open source toolsAutomatic updates, cross-platformRequires GitHub hosting
manualCustom scripts, configuration toolsInclude files with dotfiles, flexibleManual file management
npmNode.js toolsSimple, version managementRequires Node.js/npm
zsh-pluginZsh plugins from Git reposSimple, automatic updatesZsh plugins only

Install Debian-family Linux packages using APT.

import { defineTool } from "@alexgorbatchev/dotfiles";
export default defineTool((install, ctx) =>
install("apt", {
package: "ripgrep",
})
.bin("rg")
.sudo(),
);

Install tools using Homebrew package manager (macOS and Linux).

import { defineTool } from "@alexgorbatchev/dotfiles";
export default defineTool((install, ctx) =>
install("brew", {
formula: "ripgrep",
}).bin("rg"),
);

Install RPM-family Linux packages using DNF.

import { defineTool } from "@alexgorbatchev/dotfiles";
export default defineTool((install, ctx) =>
install("dnf", {
package: "ripgrep",
})
.bin("rg")
.sudo(),
);

Install Arch-family Linux packages using pacman.

import { defineTool } from "@alexgorbatchev/dotfiles";
export default defineTool((install, ctx) =>
install("pacman", {
package: "ripgrep",
})
.bin("rg")
.sudo(),
);

Install Rust tools from crates.io with cargo-quickinstall for faster downloads.

import { defineTool } from "@alexgorbatchev/dotfiles";
export default defineTool((install, ctx) =>
install("cargo", {
crateName: "ripgrep",
}).bin("rg"),
);

Download standalone binary files directly from URLs (no archive extraction).

import { defineTool } from "@alexgorbatchev/dotfiles";
export default defineTool((install, ctx) =>
install("curl-binary", {
url: "https://example.com/tool-v1.0.0-linux-amd64",
}).bin("tool"),
);

Download and execute installation scripts.

import { defineTool } from "@alexgorbatchev/dotfiles";
export default defineTool((install, ctx) =>
install("curl-script", {
url: "https://bun.sh/install",
shell: "bash",
}).bin("bun"),
);

Download and extract tarballs directly from URLs.

import { defineTool } from "@alexgorbatchev/dotfiles";
export default defineTool((install, ctx) =>
install("curl-tar", {
url: "https://releases.example.com/tool-v1.0.0.tar.gz",
}).bin("tool"),
);

Install macOS applications from DMG disk images into /Applications (silently skipped on other platforms).

import { defineTool } from "@alexgorbatchev/dotfiles";
export default defineTool((install, ctx) =>
install("dmg", {
source: {
type: "url",
url: "https://example.com/MyApp-1.0.0.dmg",
},
}),
);

DMG also supports GitHub release sources:

install("dmg", {
source: {
type: "github-release",
repo: "manaflow-ai/cmux",
assetPattern: "*macos*.dmg",
},
});

Install macOS .pkg packages with the native installer command (silently skipped on other platforms).

import { defineTool } from "@alexgorbatchev/dotfiles";
export default defineTool((install, ctx) =>
install("pkg", {
source: {
type: "url",
url: "https://example.com/MyTool.pkg",
},
binaryPath: "/usr/local/bin/my-tool",
}).bin("my-tool"),
);

Install tools from Gitea, Forgejo, or Codeberg releases with automatic asset selection.

import { defineTool } from "@alexgorbatchev/dotfiles";
export default defineTool((install, ctx) =>
install("gitea-release", {
instanceUrl: "https://codeberg.org",
repo: "owner/repository",
}).bin("tool"),
);

Install tools from GitHub releases with automatic asset selection and extraction.

import { defineTool } from "@alexgorbatchev/dotfiles";
export default defineTool((install, ctx) =>
install("github-release", {
repo: "owner/repository",
}).bin("tool"),
);

Install files from your dotfiles directory (custom scripts, pre-built binaries) or configuration-only tools. Can be called without params: install('manual').

import { defineTool } from "@alexgorbatchev/dotfiles";
// With binary installation
export default defineTool((install, ctx) =>
install("manual", {
binaryPath: "./bin/my-script.sh",
}).bin("my-script"),
);
// Without params (shell-only or dependency wrapper)
export default defineTool((install) =>
install("manual")
.bin("tokscale")
.dependsOn("bun")
.zsh((shell) =>
shell.functions({
tokscale: `bun x tokscale@latest`,
}),
),
);
// Configuration-only
export default defineTool((install, ctx) => install().zsh((shell) => shell.aliases({ ll: "ls -la" })));

Install tools published as npm packages.

import { defineTool } from "@alexgorbatchev/dotfiles";
export default defineTool((install, ctx) =>
install("npm", {
package: "prettier",
}).bin("prettier"),
);

Clone Git repositories for zsh plugins.

import { defineTool } from "@alexgorbatchev/dotfiles";
export default defineTool((install, ctx) =>
install("zsh-plugin", {
repo: "jeffreytse/zsh-vi-mode",
}).zsh((shell) => shell.always(`source "${ctx.currentDir}/zsh-vi-mode.plugin.zsh"`)),
);

The manual method is the unified approach for binary installation from your dotfiles directory.

  • You have custom scripts or binaries to include with your dotfiles
  • You want the system to manage and version your tool files
  • You need shims generated for your custom tools
  • You want to distribute pre-built binaries with your dotfiles

Example: Including a custom deployment script with your dotfiles.

import { defineTool } from "@alexgorbatchev/dotfiles";
export default defineTool((install, ctx) =>
install("manual", {
binaryPath: "./scripts/deploy.sh",
}).bin("deploy"),
);
  • You only need shell configuration (aliases, environment, symlinks)
  • Tools are managed entirely outside the dotfiles system
  • You don’t want any binary installation or management
  • Creating configuration-only “tools”

Example: Setting up shell aliases and environment variables.

import { defineTool } from "@alexgorbatchev/dotfiles";
export default defineTool((install, ctx) =>
install().zsh((shell) =>
shell
.aliases({
ll: "ls -la",
})
.env({
EDITOR: "vim",
}),
),
);

Most installation methods support these common concepts:

  • Version Selection: Specify exact versions or use constraints
  • Platform Detection: Automatic selection of appropriate binaries
  • Binary Path: Specify which file is the main executable
  • Asset Selection: Choose the right download for your platform
  • Environment Variables: Set env for installation (static or dynamic)

All installation methods support an env parameter for setting environment variables during installation:

// Static environment variables
install("github-release", {
repo: "owner/tool",
env: { CUSTOM_FLAG: "true" },
}).bin("tool");
// Dynamic environment variables
install("curl-script", {
url: "https://example.com/install.sh",
shell: "bash",
env: (ctx) => ({ INSTALL_DIR: ctx.stagingDir }),
}).bin("tool");

Dynamic env functions receive a context with:

  • projectConfig - Full project configuration
  • stagingDir - Temporary installation directory

For curl-script, the context also includes scriptPath.