Manage /etc/hosts from a YAML config: groups, zone files, remote blocklists, backups.
Entries live in the config; hostsctl renders them into a block between markers inside
/etc/hosts. Everything outside those markers — system lines, other tools' blocks, hand
edits — is carried into the new file byte for byte and is never removed.
Русская версия: README.ru.md · Docs: https://jtprogru.github.io/hostsctl/
brew install jtprogru/tap/hostsctl
# or
cargo install hostsctl
# or
curl -fsSL https://raw.githubusercontent.com/jtprogru/hostsctl/main/scripts/install.sh | shPrebuilt archives for Linux (glibc and musl, x86_64 and aarch64) and macOS (Apple
silicon and Intel) are on the releases page,
each with a sha256, a keyless cosign signature and a SLSA provenance attestation.
hostsctl init # ~/.config/hostsctl/config.yaml
hostsctl add 127.0.0.1 k8s.orb.local --comment orbstack
hostsctl diff # what would change; writes nothing
sudo hostsctl apply127.0.0.1 localhost ← system lines, untouched
255.255.255.255 broadcasthost
# >>> hostsctl begin >>>
# generated by hostsctl 2026-08-11 17:15
# source: /Users/you/.config/hostsctl/config.yaml — edit that, not this block
# --- local — Local development ---
127.0.0.1 k8s.orb.local # orbstack
# <<< hostsctl end <<<
- Groups. A set of entries that switches on and off as a whole, so turning a blocklist off for an afternoon does not mean deleting it.
- Zone files. Keep everything in one
config.yaml, or spread it over files in plain hosts syntax or YAML. Edits made through the CLI go back to the file the group came from, in that file's format. - Remote blocklists. Attach a hosts list by URL, with
rewrite_ipand an allowlist. Lists are cached and refreshed withETag;applyreads only the cache and never touches the network. - Backups. A snapshot before every write, including before a restore.
- A linter.
hostsctl checkreports what/etc/hostswould silently ignore — wildcards, ports in a hostname, addresses that are not addresses.
- Everything outside the markers is preserved, checked by tests against a copy of a real
/etc/hosts. - The write is atomic — temporary file,
fsync,rename— and preserves the target's mode and owner. - A result without
127.0.0.1 localhostis refused before anything is written. - Under
sudo, the config and cache still come from the invoking user's home directory, and files created as root are handed back to them. No root-owned files in~/.config.
hostsctl list --all # entries, including disabled ones
hostsctl search orb
hostsctl rm sre-mcp.local # by hostname or by address
hostsctl disable k8s.orb.local # stays in the config, leaves /etc/hosts
hostsctl status # config, block, groups, backups
sudo hostsctl off # remove the block, keep the config
sudo hostsctl backup restore
hostsctl group list
hostsctl group add work --file zones/20-work.yaml
hostsctl zone add 'legacy/*.hosts'
hostsctl source add <url> --group ads --rewrite-ip 0.0.0.0 --update
hostsctl completions zshThe full reference is at https://jtprogru.github.io/hostsctl/reference/cli/, and
hostsctl --help prints the same thing.
Linux or macOS. There is no Windows build: hostsctl is built on /etc/hosts, libc and
the platform's DNS cache flush.
Commands that write to /etc/hosts need root; list, diff, status, check, search
and source update do not. Without permission hostsctl does not try to work around it — it
prints the sudo command to re-run and exits with code 4.
make # every target
make test # unit + integration against a temporary hosts file
make ci # what CI runs: lint, tests, generated docs, MSRVSee CONTRIBUTING.md.
MIT — see LICENSE.