{"id":35128954,"url":"https://github.com/serkanyersen/dotstate","last_synced_at":"2026-01-24T08:11:59.024Z","repository":{"id":330057140,"uuid":"1119888702","full_name":"serkanyersen/dotstate","owner":"serkanyersen","description":"A modern, secure, and user-friendly dotfile manager built with Rust","archived":false,"fork":false,"pushed_at":"2026-01-21T02:54:54.000Z","size":1704,"stargazers_count":245,"open_issues_count":2,"forks_count":7,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-01-21T08:14:07.734Z","etag":null,"topics":["brew","cli","crates-io","dotfiles","ratatui","rust","tui"],"latest_commit_sha":null,"homepage":"https://dotstate.serkan.dev","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/serkanyersen.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["serkanyersen"],"patreon":"serkanyersen","open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"lfx_crowdfunding":null,"custom":null}},"created_at":"2025-12-20T03:35:57.000Z","updated_at":"2026-01-21T02:54:58.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/serkanyersen/dotstate","commit_stats":null,"previous_names":["serkanyersen/dotstate"],"tags_count":32,"template":false,"template_full_name":null,"purl":"pkg:github/serkanyersen/dotstate","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/serkanyersen%2Fdotstate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/serkanyersen%2Fdotstate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/serkanyersen%2Fdotstate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/serkanyersen%2Fdotstate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/serkanyersen","download_url":"https://codeload.github.com/serkanyersen/dotstate/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/serkanyersen%2Fdotstate/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28720454,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-24T05:53:42.649Z","status":"ssl_error","status_checked_at":"2026-01-24T05:53:41.698Z","response_time":89,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["brew","cli","crates-io","dotfiles","ratatui","rust","tui"],"created_at":"2025-12-28T04:27:29.479Z","updated_at":"2026-01-24T08:11:59.016Z","avatar_url":"https://github.com/serkanyersen.png","language":"Rust","funding_links":["https://github.com/sponsors/serkanyersen","https://patreon.com/serkanyersen"],"categories":[],"sub_categories":[],"readme":"# DotState\n\n\u003e **A modern, secure, and user-friendly dotfile manager built with Rust**\n\nDotState is a terminal-based tool that helps you manage your dotfiles effortlessly. Whether you're syncing your configuration across multiple machines or setting up a new development environment, DotState makes it simple, safe, and fast.\n\n## Demo\n\nhttps://github.com/user-attachments/assets/9be0df5e-87ce-4b61-ae0f-1c8ffe94cb36\n\n## Why DotState?\n\nManaging dotfiles can be a pain. You want your `.zshrc`, `.vimrc`, and other config files synced across machines, but traditional solutions are either too complex, insecure, or require too much manual work.\n\n**DotState solves this by being:**\n\n- 🦀 **Built with Rust** - Fast, memory-safe, and reliable\n- 🔒 **Secure by design** - No shell injection vulnerabilities, safe file operations\n- 🎨 **Beautiful TUI** - Intuitive interface that doesn't require learning Git\n- ⚡ **Lightning fast** - Non-blocking operations, instant feedback\n- 🛡️ **Safe** - Automatic backups before any file operations\n- 🔄 **Git-powered** - Store dotfiles in GitHub, GitLab, Bitbucket, or any git host\n\n## What Makes DotState Different?\n\n### Traditional Dotfile Managers\n\n- Require Git knowledge\n- Manual symlink management\n- No built-in backup system\n- Complex setup process\n\n### DotState\n\n- **Zero Git knowledge required** - We handle everything\n- **Automatic symlink management** - Files are linked automatically\n- **Built-in backups** - Your files are safe before any operation\n- **One-command setup** - Get started in seconds\n- **Profile support** - Separate configs for work, personal, Mac, Linux, etc.\n- **Package management** - Track and install CLI tools per profile\n- **Beautiful TUI** - Visual interface with mouse support\n\n## Features\n\n### 🎯 Core Features\n\n- **Profile Management**: Create separate profiles for different contexts (work, personal, Mac, Linux, etc.)\n- **Common Files Support**: Share dotfiles (like `.gitconfig` or `.tmux.conf`) across all profiles automatically.\n- **Flexible Git Sync**: Automatic sync with GitHub, GitLab, Bitbucket, or any git host\n- **Two Setup Modes**: Let DotState create a GitHub repo for you, or use your own repository\n- **Smart File Detection**: Automatically finds common dotfiles in your home directory\n- **Safe Operations**: Automatic backups before any file modification\n- **Symlink Management**: Automatic creation and management of symlinks\n- **Custom Files**: Add any file or directory, not just dotfiles\n\n### 📦 Package Management\n\n- **CLI Tool Tracking**: Define and track CLI tools and dependencies per profile\n- **Multi-Manager Support**: Works with Homebrew, Cargo, npm, pip, and more\n- **Installation Flow**: Check what's missing and install with one command\n- **Custom Packages**: Support for custom installation scripts\n\n### 🎨 User Experience\n\n- **Beautiful TUI**: Modern terminal interface built with Ratatui\n- **Mouse Support**: Click to navigate and interact\n- **Real-time Feedback**: See what's happening as it happens\n- **Error Recovery**: Clear error messages with actionable guidance\n- **CLI \u0026 TUI**: Full-featured CLI for automation, beautiful TUI for interactive use\n- **Customizable Keymaps**: Configurable keyboard shortcuts with preset support (Standard, Vim, Emacs) and custom overrides\n\n### 🔒 Security\n\n- **No Shell Injection**: Direct command execution, no shell interpretation\n- **Safe File Operations**: Validates paths, prevents dangerous operations\n- **Secure GitHub Integration**: Token-based authentication\n- **Backup System**: Automatic backups before any destructive operation\n\n## Installation\n\n### Prebuilt from website (Recommended)\n\n[Installation Guide](https://dotstate.serkan.dev/#installation)\n\n```bash\ncurl -fsSL https://dotstate.serkan.dev/install.sh | bash\"\n```\n\n### Using Cargo\n\n```bash\ncargo install dotstate\n```\n\n### Using Homebrew\n\n```bash\nbrew tap serkanyersen/dotstate\nbrew install dotstate\n```\n\nOr use the direct install:\n\n```bash\nbrew install serkanyersen/dotstate/dotstate\n```\n\n## Quick Start\n\n1. **Launch DotState**:\n\n   ```bash\n   dotstate\n   ```\n\n2. **First-time Setup**:\n   - Choose how to set up your repository:\n     - **Option A: Create for me (GitHub)** - DotState creates a repo on GitHub\n       - Enter your GitHub token (create one at [github.com/settings/tokens](https://github.com/settings/tokens))\n       - **Tip**: You can also set the `DOTSTATE_GITHUB_TOKEN` environment variable\n       - Choose repository name and visibility (private/public)\n     - **Option B: Use my own repository** - Bring your own git repo\n       - Create a repo on any git host (GitHub, GitLab, Bitbucket, etc.)\n       - Clone it locally and set up your credentials\n       - Point DotState to your local repo path\n\n3. **Add Your Files**:\n   - Navigate to \"Manage Files\"\n   - Select files to sync (they're automatically added)\n   - Files are moved to the repo and symlinked automatically\n\n4. **Sync with Remote**:\n   - Go to \"Sync with Remote\"\n   - Your files are committed, pulled, and pushed automatically\n\nThat's it! Your dotfiles are now synced and ready to use on any machine.\n\n## CLI Usage\n\nDotState also provides a powerful CLI for automation:\n\n```bash\n# List all synced files\ndotstate list\n\n# Add a file to sync\ndotstate add ~/.myconfig\n\n# Sync with remote (commit, pull, push)\ndotstate sync\n\n# Sync with custom commit message\ndotstate sync -m \"My custom commit message\"\n\n# Activate symlinks (useful after cloning on a new machine)\ndotstate activate\n\n# Deactivate symlinks (restore original files)\ndotstate deactivate\n\n# Check for updates and upgrade\ndotstate upgrade\n\n# Show help\ndotstate help\n```\n\n## How It Works\n\n1. **Storage**: Your dotfiles are stored in a Git repository (default: `~/.config/dotstate/storage`)\n2. **Symlinks**: Original files are replaced with symlinks pointing to the repo\n3. **Profiles**: Different profiles can have different sets of files\n4. **Common Files**: Files that are shared across all profiles are stored in the `common` section and linked regardless of the active profile\n5. **Sync**: Changes are committed and synced with GitHub automatically\n\n## Configuration\n\n### Repository Setup Modes\n\nDotState supports two repository setup modes:\n\n#### GitHub Mode (Automatic)\n\nLet DotState create and manage a GitHub repository for you. Requires a GitHub Personal Access Token.\n\n**GitHub Token Configuration:**\n\n1. **Environment Variable** (Recommended for automation):\n\n   ```bash\n   export DOTSTATE_GITHUB_TOKEN=ghp_your_token_here\n   ```\n\n   The environment variable takes precedence over the config file token.\n\n2. **Config File**: The token can be stored in the config file (set during first-time setup).\n\n#### Local Mode (Bring Your Own Repo)\n\nUse any existing git repository from any host (GitHub, GitLab, Bitbucket, self-hosted, etc.).\n\n**Setup:**\n\n1. Create a repository on your preferred git host\n2. Clone it locally: `git clone \u003curl\u003e ~/.config/dotstate/storage`\n3. Ensure you can push: `git push origin main`\n4. In DotState, choose \"Use my own repository\" and enter the path\n\n**Benefits of Local Mode:**\n\n- Works with any git host\n- Uses your existing SSH keys or git credentials\n- No GitHub token required\n\n### Update Notifications\n\nDotState automatically checks for updates and shows a notification in the main menu when a new version is available. You can also check manually:\n\n```bash\n# Check for updates interactively\ndotstate upgrade\n\n# Just check without prompting\ndotstate upgrade --check\n```\n\n**Configuration:**\nUpdate checks can be configured in `~/.config/dotstate/config.toml`:\n\n```toml\n[updates]\ncheck_enabled = true       # Set to false to disable update checks\ncheck_interval_hours = 24  # How often to check (default: 24 hours)\n```\n\n### Theme Configuration\n\nDotState supports both light and dark themes that automatically adapt to your terminal background. The theme affects all UI elements including colors, borders, text, and syntax highlighting in file previews.\n\n**Changing the Theme:**\n\nEdit `~/.config/dotstate/config.toml` and set the `theme` option:\n\n```toml\ntheme = \"dark\"   # For dark terminal backgrounds (default)\ntheme = \"light\"  # For light terminal backgrounds\ntheme = \"nocolor\" # Disable all UI colors (same as NO_COLOR=1 / --no-colors)\n```\n\n**Theme Features:**\n\n- **Automatic Syntax Highlighting**: File preview syntax highlighting automatically matches your selected theme\n- **Consistent Colors**: All UI elements (headers, footers, borders, lists, text) use theme-appropriate colors\n- **Terminal Compatibility**: Works with both light and dark terminal themes\n- **No Colors Mode**: Use `--no-colors` CLI flag or `NO_COLOR=1` to disable all colors:\n  ```bash\n  dotstate --no-colors\n  ```\n  Or:\n  ```bash\n  NO_COLOR=1 dotstate\n  ```\n\n**What Changes with Theme:**\n\n- Text colors (dark text on light backgrounds, light text on dark backgrounds)\n- Border colors (adjusted for visibility)\n- Highlight colors (selection indicators, focused elements)\n- Syntax highlighting themes in file previews\n- Status colors (success, warning, error indicators)\n\n### Keymap Configuration\n\nDotState supports customizable keyboard shortcuts with preset keymaps (Standard, Vim, Emacs) and custom key binding overrides. The keymap system allows you to use your preferred keyboard layout and override any action with any key combination.\n\n**Available Presets:**\n\n- **Standard**: Arrow keys (↑↓), Enter, Esc, standard navigation\n- **Vim**: Vim-style navigation (hjkl for movement, q to quit, etc.)\n- **Emacs**: Emacs-style navigation (Ctrl+N/P for up/down, Ctrl+G to quit, etc.)\n\n**Changing the Preset:**\n\nEdit `~/.config/dotstate/config.toml` and set the `preset` option in the `[keymap]` section:\n\n```toml\n[keymap]\npreset = \"vim\"  # Options: \"standard\", \"vim\", \"emacs\"\n```\n\n**Custom Key Binding Overrides:**\n\nYou can override any key binding with custom keys. Overrides take precedence over preset bindings and shadow preset bindings for the same action.\n\nExample configuration:\n\n```toml\n[keymap]\npreset = \"vim\"\n\n# Override 'x' to quit instead of 'q'\n[[keymap.overrides]]\nkey = \"x\"\naction = \"quit\"\n\n# Override 'w' to move up instead of 'k'\n[[keymap.overrides]]\nkey = \"w\"\naction = \"move_up\"\n\n# Use Ctrl+H for help\n[[keymap.overrides]]\nkey = \"ctrl+h\"\naction = \"help\"\n```\n\n**Available Actions (all in snake_case):**\n\n- **Navigation**: `move_up`, `move_down`, `move_left`, `move_right`, `page_up`, `page_down`, `go_to_top`, `go_to_end`, `home`, `end`\n- **Selection**: `confirm`, `cancel`, `toggle_select`, `select_all`, `deselect_all`\n- **Global**: `quit`, `help`\n- **Actions**: `delete`, `edit`, `create`, `search`, `refresh`, `sync`, `check_status`, `install`\n- **Text editing**: `backspace`, `delete_char`\n- **Navigation**: `next_tab`, `prev_tab`\n- **Scroll**: `scroll_up`, `scroll_down`\n- **Prompts**: `yes`, `no`\n- **Forms**: `save`, `toggle_backup`\n\n**Key Format Examples:**\n\n- Single keys: `\"j\"`, `\"k\"`, `\"q\"`, `\"x\"`\n- Special keys: `\"up\"`, `\"down\"`, `\"enter\"`, `\"esc\"`, `\"tab\"`, `\"space\"`\n- Function keys: `\"f1\"`, `\"f2\"`, etc.\n- Modifier combinations: `\"ctrl+n\"`, `\"ctrl+shift+j\"`, `\"ctrl+h\"`\n\n**How Overrides Work:**\n\n- Overrides take precedence over preset bindings\n- When you override an action (e.g., `move_up`), all preset bindings for that action are shadowed/removed\n- If you override `move_up` with `\"w\"`, the original preset key (e.g., `\"k\"` in vim preset) will no longer work for that action\n- Display functions (footer hints) automatically reflect your actual key bindings, including overrides\n\n**Example:**\n\nSee `examples/keymap_override_example.toml` for a complete example configuration file.\n\n## Security Considerations\n\n- **No Shell Injection**: All commands use direct execution, not shell interpretation\n- **Path Validation**: Dangerous paths (like home directory root) are blocked\n- **Git Repository Detection**: Prevents nested Git repositories\n- **Backup System**: Automatic backups before any file operation\n- **Token Security**: GitHub tokens can be provided via `DOTSTATE_GITHUB_TOKEN` environment variable (recommended) or stored in config files with secure permissions\n\n## Requirements\n\n- **Rust**: Latest stable version (for building from source)\n- **Git**: For repository operations\n- **Git Account**: GitHub, GitLab, Bitbucket, or any git host (optional, for cloud sync)\n- **(Recommended) Nerd Fonts**: For the best visual experience, we recommend using a [Nerd Font](https://www.nerdfonts.com/) to see all icons correctly.\n\n## Project Status\n\nDotState is actively developed and ready for use. The core features are stable, and we're continuously improving based on user feedback.\n\n## Contributing\n\nWe welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.\n\n## License\n\nMIT License - see [LICENSE](LICENSE) file for details.\n\n## Acknowledgments\n\nBuilt with:\n\n- [Ratatui](https://github.com/ratatui-org/ratatui) - Beautiful TUI framework\n- [git2](https://github.com/rust-lang/git2-rs) - Git operations\n- [clap](https://github.com/clap-rs/clap) - CLI parsing\n\nBadges:\n\n\u003ca title=\"This tool is Tool of The Week on Terminal Trove, The $HOME of all things in the terminal\" href=\"https://terminaltrove.com/dotstate/\"\u003e\u003cimg width=\"180\" src=\"https://cdn.terminaltrove.com/media/badges/tool_of_the_week/svg/terminal_trove_tool_of_the_week_green_on_dark_grey_bg.svg\" alt=\"Terminal Trove Tool of The Week\" /\u003e\u003c/a\u003e\n\n## Support\n\n- **Issues**: [GitHub Issues](https://github.com/serkanyersen/dotstate/issues)\n- **Discussions**: [GitHub Discussions](https://github.com/serkanyersen/dotstate/discussions)\n\n---\n\n**Made with ❤️ and Rust**\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fserkanyersen%2Fdotstate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fserkanyersen%2Fdotstate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fserkanyersen%2Fdotstate/lists"}