I just released v1.0.0 of store --- a more powerful and simpler alternative to GNU Stow with explicit organization

Wait 5 sec.

I've been working on this for a while now and I'm genuinely proud to finally call it 1.0. store is a CLI tool for managing dotfile symlinks, and the core idea is that your dotfiles repo should be easy to understand just by looking at it. How it started This whole thing started because I was using GNU stow. stow is great for what it is, but it requires your repo to mirror the target filesystem hierarchy, it has no config file, and everything is convention-based. I kept running into limitations; no way to send one directory to multiple targets, no conflict handling, no way to skip stores per-platform. I started building store as "stow but with a config file" and it grew from there. The problem I had with other tools Along the way I looked at chezmoi and yadm too. They're both solid tools, but they never clicked with me. yadm turns your entire home directory into a git repo. It works, but it always felt like I was fighting against git's design. There's no real organization; your dotfiles are scattered across the same paths they live in on disk. Looking at the repo doesn't tell you much about what's managed and what isn't. chezmoi goes the other direction; lots of structure, but it's chezmoi's structure, not yours. Files get prefixed with dot_, private_, executable_. Templates are powerful but add complexity. The source state is an encoded representation of your filesystem, not a human-readable layout. I found myself spending more time learning chezmoi than managing my dotfiles. What store does differently store is built around one idea: your dotfiles repo should look like you organized it yourself. ~/dotfiles/ .store/config.yaml nvim/ init.lua lua/ shells/ .zshrc .bashrc config.fish git/ .gitconfig Each directory is a "store" that maps to one or more targets. The config is one YAML file: yaml stores: nvim: target: ~/.config/nvim shells: targets: - target: "~" files: [.zshrc, .bashrc] - target: ~/.config/fish files: [config.fish] git: target: ~/.config/git That's it. You look at the repo and you know what's in it. You look at the config and you know where everything goes. No encoding, no conventions to memorize, no source-state translation. It's the explicitness of a config file with the simplicity that stow got right; just symlinks. What's in 1.0 The feature set has grown well beyond what I originally set out to build, and I'm really happy with where it landed: Symlinks - whole-directory or per-file with glob patterns Multi-target stores - one directory can deploy to multiple locations (like shells above) Conflict resolution - detects existing files and offers to move them into your repo Encrypted secrets - {{ secret "github_token" }} in any config file, encrypted at rest, rendered at symlink time Platform conditionals - when: {os: linux} to skip stores on the wrong machine Ignore patterns - exclude files from symlinking with global defaults for .git/, .store/, etc. store doctor - health checks for orphaned configs, broken symlinks, missing secrets store diff - dry-run preview of what would change store import - scans for existing symlinks and generates config from them Shell completions - bash, zsh, fish, powershell New machine setup is git clone && cd dotfiles && store. That's it. Links GitHub: https://github.com/cushycush/store go install github.com/cushycush/store/cmd/store@latest Would love to hear what you think, and happy to answer questions about the design decisions.   submitted by   /u/DaCush [link]   [comments]