# hostcraft
[](https://crates.io/crates/hostcraft-cli)
[](LICENSE)
[](https://www.rust-lang.org)
A fast, cross-platform CLI for managing your system hosts file — add, remove, toggle, and list host entries directly from your terminal without ever manually editing the file.
---
## Ecosystem
| `hostcraft-core` | Shared library | ✅ Published |
| `hostcraft-cli` | Terminal interface (this crate) | ✅ Published |
| `hostcraft-gui` | Desktop GUI (Tauri) | 🚧 Planned |
---
## Features
- **List** all host entries with colour-coded active/inactive status
- **Add** a new entry with an IP address and hostname
- **Remove** entries by full or partial name match
- **Toggle** entries on/off without deleting them
- **Update** to the latest version with a single command — `hostcraft update`
- Background update checks — once every 24 hours, a notice is printed at the end of any command if a newer version is available
- Entries are never silently lost — disabled entries are preserved as commented-out lines
- Duplicate entry detection — adding the same IP + hostname twice is rejected
- IPv4 and IPv6 support
- Cross-platform — works on macOS, Linux, and Windows
- Coloured, aligned terminal output powered by `anstyle`
- Friendly error messages with platform-specific permission hints
---
## Installation
### From crates.io (recommended)
```sh
cargo install hostcraft-cli
```
This compiles the binary and places it in `~/.cargo/bin/`, which is on your `PATH` by default after a standard Rust install. Once done, `hostcraft` is available globally from any directory.
### From source
```sh
git clone https://github.com/Zaberahmed/hostcraft.git
cd hostcraft
cargo install --path cli
```
### Verify the install
```sh
hostcraft --version
```
---
## Quick Start
```sh
# See all current entries in your hosts file
hostcraft list
# Add a new entry
sudo hostcraft add myapp.local 127.0.0.1
# Disable it temporarily without removing it
sudo hostcraft toggle myapp.local
# Remove it entirely
sudo hostcraft remove myapp.local
# Update to the latest version
hostcraft update
```
> **Why sudo?** Your system hosts file is a protected system file. Reading it works without elevated privileges, but any command that writes — `add`, `remove`, `toggle` — requires `sudo` on macOS/Linux or running as Administrator on Windows.
---
## Commands
### `list`
Prints all entries in your hosts file with colour-coded status.
```sh
hostcraft list
```
**Output:**
```
127.0.0.1 localhost ● Active
255.255.255.255 broadcasthost ● Active
::1 localhost ● Active
127.0.0.1 myapp.local ○ Inactive
```
- `●` green — entry is active and in effect
- `○` red/dimmed — entry is inactive (commented out in the hosts file)
---
### `add <name> <ip>`
Adds a new active entry. The entry is immediately written to the hosts file.
```sh
sudo hostcraft add myapp.local 127.0.0.1
sudo hostcraft add staging.myapp.com 192.168.1.50
sudo hostcraft add mysite.local ::1 # IPv6
```
Adding a duplicate (same IP **and** same hostname) is rejected with an error — the file is left unchanged.
---
### `remove <name>`
Removes all entries whose hostname contains the given string. Supports partial matches.
```sh
# Remove an exact hostname
sudo hostcraft remove myapp.local
# Remove all entries matching a substring
sudo hostcraft remove myapp # removes myapp.local, myapp.dev, etc.
```
Returns an error if no matching entry is found.
---
### `toggle <name>`
Flips matching entries between active and inactive without removing them. Useful for temporarily disabling a host without losing it.
```sh
sudo hostcraft toggle myapp.local
# Before: 127.0.0.1 myapp.local
# After: # 127.0.0.1 myapp.local
sudo hostcraft toggle myapp.local
# Before: # 127.0.0.1 myapp.local
# After: 127.0.0.1 myapp.local
```
Supports partial name matching — `hostcraft toggle myapp` toggles all entries whose hostname contains `"myapp"`.
---
### `update`
Checks crates.io for a newer version of hostcraft and installs it automatically if one is available.
```sh
hostcraft update
```
If already on the latest version:
```
✓ hostcraft is up to date (v1.0.1)
```
If a newer version is found, it runs `cargo install hostcraft-cli` under the hood and streams cargo's progress live to your terminal, then confirms when done:
```
↑ Updating v1.0.1 → v1.1.0 ...
Compiling hostcraft-cli v1.1.0
...
✓ Updated to v1.1.0
```
> **Passive notices:** hostcraft also checks for updates silently in the background once every 24 hours. If a newer version is found, a notice is printed at the end of whatever command you ran:
>
> ```
> ↑ Update available: v1.0.1 → v1.1.0
> Run `hostcraft update` to install.
> ```
>
> The check runs in a background thread and does not add any latency to your command.
---
## Options
| `--file <path>` | Platform default (see below) | Override the hosts file path |
| `--help` | — | Print help for the command or subcommand |
| `--version` | — | Print the installed version |
### Default hosts file path
| macOS / Linux | `/etc/hosts` |
| Windows | `C:\Windows\System32\drivers\etc\hosts` |
### Overriding the path
The `--file` flag is useful for testing against a copy without touching your real hosts file:
```sh
hostcraft --file ./hosts-copy list
hostcraft --file ./hosts-copy add myapp.local 127.0.0.1
```
> **Note:** `--file` must come **before** the subcommand.
>
> ```sh
> ✅ hostcraft --file ./hosts-copy list
> ❌ hostcraft list --file ./hosts-copy
> ```
---
## Permissions
Writing to the system hosts file requires elevated privileges on all platforms.
### macOS / Linux
Prefix write commands with `sudo`:
```sh
sudo hostcraft add myapp.local 127.0.0.1
sudo hostcraft remove myapp.local
sudo hostcraft toggle myapp.local
```
`list` does **not** require `sudo`:
```sh
hostcraft list
```
### Windows
Run your terminal (Command Prompt or PowerShell) **as Administrator**, then use `hostcraft` normally without any prefix:
```sh
hostcraft add myapp.local 127.0.0.1
hostcraft remove myapp.local
hostcraft toggle myapp.local
```
If you forget, hostcraft will tell you:
```
✗ Error: Permission denied: run as Administrator to modify 'C:\Windows\System32\drivers\etc\hosts'
```
---
## Development
### Prerequisites
- [Rust](https://rustup.rs/) (2024 edition or later)
### Build from source
```sh
git clone https://github.com/Zaberahmed/hostcraft.git
cd hostcraft
# Build the entire workspace
cargo build
# Run directly without installing
cargo run --bin hostcraft -- list
cargo run --bin hostcraft -- add myapp.local 127.0.0.1
cargo run --bin hostcraft -- --file ./cli/hosts-copy list
```
### Re-installing after changes
If you've installed via `cargo install` and made local changes, reinstall to pick them up:
```sh
cargo install --path cli --force
```
### Project structure
```
hostcraft/
├── core/ # hostcraft-core — shared library
│ └── src/
│ ├── host/ # HostEntry, HostStatus, HostError + operations
│ │ ├── mod.rs # Public API: parse_contents, add_entry, remove_entry, toggle_entry
│ │ └── utils.rs # Internal: parse_line, is_duplicate_entry
│ └── file/ # File I/O
│ ├── mod.rs # Public API: read_file, write_file
│ └── utils.rs # Internal: write_entries
│
└── cli/ # hostcraft-cli — this crate
└── src/
├── main.rs # Entry point — parses args, wires background update check
├── command/
│ ├── mod.rs # CLI definition (Cli, Command) + run() dispatch
│ └── utils.rs # Write helpers with permission-aware error messages
├── display/
│ ├── mod.rs # Coloured output — all print functions
│ └── style.rs # ANSI style constants (pub(super))
└── update/
├── mod.rs # Update checker — public API and command handler
└── utils.rs # HTTP fetch, version compare, state file helpers
```
### Running tests
```sh
# Run all tests across the workspace
cargo test
# Run only core library tests
cargo test -p hostcraft-core
```
---
## License
MIT — see [LICENSE](LICENSE) for details.