dd_dotstore
Not Just for Dotfiles Anymore
I've been managing Linux dotfiles the same way for years: manually creating symlinks, forgetting what links where, and inevitably breaking something when I switch machines. Then I built dd_dotstore, and it turned out to be useful for way more than just dotfiles.
What It Is
dd_dotstore is a terminal UI (TUI) that takes the pain out of managing symlinks. Instead of typing `ln -s` commands and hoping you got the paths right, you get a visual tree view of your files, a fuzzy-search destination browser, and bulk operations that actually make sense.
Think of it as a symlink manager with training wheels that you never outgrow.
The Dotfiles Workflow (The Obvious Use Case)
Everyone's got a dotfiles repo. Neovim configs, shell profiles, window manager settings—all scattered across `~/.config/`, `~/`, and whatever random paths various tools decided to use. dd_dotstore lets you:
- Point it at your dotfiles repository
- Browse the tree and select what you want to link
- Assign destinations using a fuzzy-search browser (hit `~` for home, `g/G` to jump, type to filter)
- Bulk-create symlinks with `s`, bulk-remove with `x`
- Undo mistakes with `u` (last 10 actions, persisted across sessions)
The status panel shows you exactly what got linked where: green checkmarks for valid symlinks, red X's for broken ones. No more guessing.
The Real Game-Changer: AI Skill Sharing
Here's where it gets interesting. I've been collecting AI skill files—Markdown prompts and instructions I share between Claude, ChatGPT, and my own local LLM tools. These lived in a scattered mix of folders, synced haphazardly through various means.
Then I realized: dd_dotstore handles this perfectly.
I created a central `ai-skills/` repository with organized skill files:
ai-skills/
├── coding/
│ ├── rust-patterns.md
│ ├── debugging-strategies.md
│ └── refactoring-techniques.md
├── writing/
│ ├── technical-blogs.md
│ └── documentation-style.md
└── analysis/
├── code-review.md
└── architecture-review.md
With dd_dotstore, I can:
- Link specific skill files to where each AI tool expects them
- Test new skills in isolation by swapping symlinks
- Bulk-swap entire skill sets for different contexts (coding mode vs writing mode)
- Export configurations when I set up a new machine
Want to try a new Claude skill without committing to it? Link it temporarily, test it, remove it with `x` if it doesn't work out. Your central repository stays clean.
Other Surprising Use Cases
Project Templates
Got boilerplate files you copy into every new project? Instead of copy-pasting, symlink them from a templates repository. When you update the template, every project using it gets the update automatically.
Documentation Hubs
I keep architecture decision records (ADRs) and design docs in a central repo, then symlink them into project-specific `docs/` folders. One source of truth, multiple access points.
Shared Configuration Across Teams
Company-wide linting configs, Git hooks, IDE settings—centralize them in a repo, let team members symlink what they need. When standards change, update once, everyone gets it on next pull.
Temporary Experimentation
Working on a feature that needs a different config? Create the variant in your dotstore repo, symlink it temporarily, switch back with `u` when done. Your experiments are versioned and reversible.
Safety Features That Actually Work
dd_dotstore was built with the understanding that symlinks are dangerous when used recklessly:
- Overwrite warnings: Before replacing real files with symlinks, you get a confirmation modal
- Destination lock protection: Can't accidentally change a destination while a symlink still exists there
- Undo history: Last 10 actions remembered, even across app restarts
- Status icons: See at a glance whether symlinks are valid (✓), broken (✗), or unknown (?)
The Technical Bits
Built in Rust with ratatui for the interface. It uses your standard `.dd_dotstore.json` for persistence, stores exports in `~/.dd_dotstore/exports/`, and plays nice with fuzzy filtering, vim-style keybindings (`j/k/h/l`), and the Catppuccin color scheme.
- `cargo run` for development
- `cargo build --release` for the binary
- Install to `~/.local/bin/dd_dotstore` for daily use
Supports project root override via `--root` or positional path, so you can manage multiple repositories without CDing around.
Why a TUI?
GUIs for this kind of task feel heavy. CLI-only tools make you remember path structures and commands. A TUI hits the sweet spot: keyboard-driven speed with visual feedback that prevents mistakes.
Plus, it runs over SSH. Manage your dotfiles on a remote server the same way you do locally.
Get It
The project is at v1.0.0, MIT licensed, and ready for daily use. Whether you're a dotfiles perfectionist, an AI prompt engineer, or just someone who hates typing long paths correctly, dd_dotstore makes symlink management actually pleasant.
Stop fighting with `ln -s` and start managing your configuration like a civilized human being.
What unexpected tool combinations have you discovered? I've found that the best workflows come from repurposing tools beyond their original design. Reply and share your favorites.
dd_dotstore is available at https://bitbucket.org/ldnddev/dd_dotstore — pulls, forks, and feedback welcome.
Run
# Development
cargo run
# Development with explicit project root
cargo run -- --root /path/to/dotfiles
cargo run -- /path/to/dotfiles
# CLI help
cargo run -- --help
# Release build
cargo build --release
./target/release/dd_dotstore
Install
# Build release binary
cargo build --release
# Install to ~/.local/bin/dd_dotstore
mkdir -p "$HOME/.local/bin"
cp target/release/dd_dotstore "$HOME/.local/bin/dd_dotstore"
chmod +x "$HOME/.local/bin/dd_dotstore"
# Ensure ~/.local/bin is on PATH (bash)
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
Until next time, Jared Lyvers
Ready To Go!
Have a project brewing? Let’s chat and explore how we can help you bring it to life. Share your ideas and let’s get started.