Skip to content

Repository files navigation

Statemate

Declarative system configuration management. Manage dotfiles, configs, and packages across machines.

Features

  • Stow-style sources — organize configs by app, deployed relative to home
  • Profiles — machine-specific configs with auto-detection
  • Templates — Go templates with the sprig function library
  • Encryption — age encryption for sensitive files
  • Secrets — Bitwarden references resolved from an encrypted cache
  • Packages — declarative package management (brew, pacman, AUR)
  • Scripts — lifecycle scripts (before/after apply, run once, on change)

Installation

# Homebrew (macOS/Linux)
brew install subbeh/tap/statemate

# Arch (AUR)
paru -S statemate-bin

# Go
go install github.com/subbeh/statemate/cmd/mate@latest

# From source
git clone https://github.com/subbeh/statemate
cd statemate && make build-all

Quick Start

mkdir ~/dotfiles && cd ~/dotfiles
mate init                      # create mate.yaml

mate add ~/.config/nvim/init.lua
mate status                    # what would change
mate diff                      # how it would change
mate apply                     # make it so

A source directory is deployed relative to your home directory:

~/dotfiles/
  mate.yaml
  nvim/
    .config/nvim/init.lua      →  ~/.config/nvim/init.lua
  zsh/
    .zshrc                     →  ~/.zshrc

Behavior is controlled by # suffixes on filenames, stripped from the target:

.ssh/config#encrypted#perm:600         encrypted in the repo, mode 0600 deployed
gitconfig#template                     rendered as a Go template
.gitconfig#profile:work                only on machines matching the work profile
.claude/settings.json#import           app owns it; changes flow back to the repo

Documentation

Full documentation is in docs/:

Guide Contents
Getting Started Install, create a repository, add your first file
Concepts Sources, targets, state, and how a change is detected
Configuration mate.yaml, .mate.yaml, profiles, local overrides
File Attributes Every # suffix and what it does
Templates Variables and functions available when rendering
Secrets Bitwarden references and the encrypted cache
Scripts Lifecycle scripts, frequency, timing
Packages Declarative packages across brew, pacman, and the AUR
Command Reference Every command and flag

mate <command> --help gives the same reference in the terminal.

Configuration at a glance

# mate.yaml
sources: [nvim, zsh, git]

profiles:
  work:
    extends: base
    detection:
      hostname: "work-*"
    variables:
      email: "me@company.com"
    packages:
      brew: [slack]

age:
  identity: "~/.config/statemate/key.txt"
  recipients: ["age1..."]

packages:
  brew: [ripgrep, fd]

See Configuration for every key.

Shell Completions

mate completion bash > /etc/bash_completion.d/mate
mate completion zsh > "${fpath[1]}/_mate"
mate completion fish > ~/.config/fish/completions/mate.fish

Contributing

See CONTRIBUTING.md. In short: make test and make lint must pass, user-visible changes need a CHANGELOG entry, and make docs regenerates the command reference when help text changes.

License

MIT

About

No description, website, or topics provided.

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages