hostparty
v2.1.0
Published
Programmatic and CLI editing for OS hosts file
Maintainers
Readme
hostparty
Cross-platform CLI and JavaScript API for managing your hosts file.
Installation
# CLI usage
npm install -g hostparty
# Library usage
npm install hostpartyQuick Start
As a Library
import party from 'hostparty';
// Add hosts to an IP
await party.add('127.0.0.1', ['myapp.local', 'api.local']);
// List all host entries
const hosts = await party.list();
// { '127.0.0.1': ['myapp.local', 'api.local'] }
// Remove specific hostnames
await party.removeHost('api.local');
// Remove all entries for an IP
await party.removeIP('127.0.0.1');Configuration
import party from 'hostparty';
// Custom hosts file path and force mode
party.setup({
path: '~/my-own/hosts',
force: true,
dryRun: false, // Preview changes without writing
autoBackup: true, // Auto-backup before changes
maxBackups: 10 // Max backups to keep
});
await party.removeIP('::1'); // Normally protected, but force allows itCommonJS
const party = require('hostparty');
await party.add('127.0.0.1', ['example.local']);API Reference
All methods return Promises.
party.add(ip, hosts)
Add hostname(s) to an IP address.
| Parameter | Type | Description |
|-----------|------|-------------|
| ip | string | IP address to map to |
| hosts | string \| string[] | Hostname(s) to add |
await party.add('127.0.0.1', ['site.local', 'api.local']);party.list([hostname])
List all entries, optionally filtered by hostname.
| Parameter | Type | Description |
|-----------|------|-------------|
| hostname | string | Optional hostname to filter by |
const all = await party.list();
const filtered = await party.list('myapp.local');party.removeIP(ips)
Remove all entries for the specified IP address(es).
| Parameter | Type | Description |
|-----------|------|-------------|
| ips | string \| string[] | IP address(es) to remove |
await party.removeIP(['127.0.0.1', '8.8.4.4']);party.removeHost(hosts)
Remove specific hostname(s) from any IP.
| Parameter | Type | Description |
|-----------|------|-------------|
| hosts | string \| string[] | Hostname(s) to remove |
await party.removeHost('old-site.local');party.renameHost(oldHostName, newHostName)
Rename a hostname while keeping its IP binding.
| Parameter | Type | Description |
|-----------|------|-------------|
| oldHostName | string | Current hostname |
| newHostName | string | New hostname |
await party.renameHost('old-app.local', 'new-app.local');party.moveHostname(hostname, toIP)
Move a hostname from its current IP to a new IP.
| Parameter | Type | Description |
|-----------|------|-------------|
| hostname | string | Hostname to move |
| toIP | string | Destination IP address |
await party.moveHostname('myapp.local', '192.168.1.100');party.replaceIP(fromIP, toIP, [keepSource])
Migrate all hostnames from one IP to another.
| Parameter | Type | Description |
|-----------|------|-------------|
| fromIP | string | Source IP address |
| toIP | string | Destination IP address |
| keepSource | boolean | Keep source IP (copy mode). Default: false |
// Move all hostnames (removes source IP)
await party.replaceIP('192.168.1.1', '192.168.1.2');
// Copy all hostnames (keeps source IP)
await party.replaceIP('192.168.1.1', '192.168.1.2', true);party.searchByIP(ip)
Find all hostnames mapped to a given IP address.
| Parameter | Type | Description |
|-----------|------|-------------|
| ip | string | IP address to search for |
Returns { ip, hostnames } or null if not found.
const result = await party.searchByIP('127.0.0.1');
// { ip: '127.0.0.1', hostnames: ['localhost', 'myapp.local'] }party.disable(ips)
Disable IP entries by commenting them out.
| Parameter | Type | Description |
|-----------|------|-------------|
| ips | string \| string[] | IP address(es) to disable |
await party.disable('192.168.1.100');
// Entry becomes: # 192.168.1.100 myapp.localparty.enable(ips)
Re-enable previously disabled IP entries.
| Parameter | Type | Description |
|-----------|------|-------------|
| ips | string \| string[] | IP address(es) to enable |
await party.enable('192.168.1.100');
// Restores: 192.168.1.100 myapp.localparty.getStats()
Get statistics about the hosts file.
const stats = await party.getStats();
// {
// activeIPs: 12,
// disabledIPs: 2,
// totalIPs: 14,
// totalHostnames: 28,
// uniqueHostnames: 25
// }party.createBackup()
Create a backup of the current hosts file.
const backupPath = await party.createBackup();
// ~/.hostparty-backups/hosts.backup.2024-01-15T10-30-00-000Zparty.listBackups()
List all available backup files.
const backups = await party.listBackups();
// [{ filename, path, timestamp }, ...]party.restore([backupPath])
Restore the hosts file from a backup.
| Parameter | Type | Description |
|-----------|------|-------------|
| backupPath | string | Path to backup file. Default: latest backup |
// Restore from latest backup
await party.restore();
// Restore from specific backup
await party.restore('/path/to/backup');party.setup(options)
Configure hostparty. Returns the party instance for chaining.
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| path | string | auto | Custom path to hosts file |
| force | boolean | false | Bypass protection on system entries |
| dryRun | boolean | false | Preview changes without writing |
| autoBackup | boolean | true | Auto-backup before changes |
| maxBackups | number | 10 | Maximum backups to retain |
party.setup({ path: '/custom/hosts', force: true }).removeIP('::1');CLI Reference
Usage: hostparty [options] [command]
Commands:
list [hostname] Output hosts file, optionally filtered
add [ip] [hosts...] Add hostname(s) to an IP address
remove-ip [ips...] Remove all entries for IP address(es)
remove-host [hosts...] Remove specific hostname(s)
rename-host [oldHost] [newHost] Rename a hostname
move-hostname [hostname] [toIP] Move a hostname to a different IP
search-ip [ip] Find all hostnames for an IP
replace-ip [fromIP] [toIP] Migrate hostnames between IPs
disable [ips...] Comment out IP entries
enable [ips...] Restore commented IP entries
stats Show hosts file statistics
backup Create a backup
list-backups List available backups
restore [filename] Restore from backup
Options:
--path [path] Path to hosts file (auto-detected by default)
--force Bypass validation on protected entries
--no-group Don't group output by IP
--dry-run Preview changes without applying
--no-backup Skip automatic backup
--json Output in JSON format (list, stats)
--csv Output in CSV format (list)
--keep-source Keep source IP when using replace-ip
-h, --help Show help
-V, --version Show versionExamples
# Add hosts
hostparty add 127.0.0.1 myapp.local api.local
# List all entries
hostparty list
# List entries matching a hostname
hostparty list myapp
# List in JSON format
hostparty list --json
# List in CSV format
hostparty list --csv
# Remove all entries for an IP
hostparty remove-ip 127.0.0.1
# Remove specific hostnames
hostparty remove-host old-site.local
# Rename a hostname
hostparty rename-host old.local new.local
# Move a hostname to a different IP
hostparty move-hostname myapp.local 192.168.1.100
# Find hostnames for an IP
hostparty search-ip 127.0.0.1
# Migrate all hostnames from one IP to another
hostparty replace-ip 192.168.1.1 192.168.1.2
# Copy hostnames (keep source)
hostparty replace-ip 192.168.1.1 192.168.1.2 --keep-source
# Temporarily disable an IP entry
hostparty disable 192.168.1.100
# Re-enable a disabled entry
hostparty enable 192.168.1.100
# Preview changes without applying
hostparty add 127.0.0.1 test.local --dry-run
# Show statistics
hostparty stats
# Create a backup
hostparty backup
# List available backups
hostparty list-backups
# Restore from latest backup
hostparty restore
# Restore from specific backup
hostparty restore hosts.backup.2024-01-15T10-30-00-000Z
# Skip auto-backup for a change
hostparty add 127.0.0.1 temp.local --no-backupSmart Argument Detection
If you accidentally swap arguments, hostparty detects and offers to correct:
$ hostparty add example.com 192.168.1.100
Warning: Arguments might be swapped. Did you mean: 192.168.1.100 example.com?
Use the suggested order? (y/n): y
Using corrected order.
1 hostname(s) added to IP 192.168.1.100Backup & Restore
Hostparty automatically creates backups before making changes. Backups are stored in ~/.hostparty-backups/.
# Manual backup
hostparty backup
# List backups
hostparty list-backups
# Found 3 backup(s):
# hosts.backup.2024-01-15T10-30-00-000Z
# hosts.backup.2024-01-14T15-45-00-000Z
# hosts.backup.2024-01-13T09-00-00-000Z
# Restore latest
hostparty restore
# Restore specific backup
hostparty restore hosts.backup.2024-01-14T15-45-00-000Z
# Skip auto-backup for a single operation
hostparty remove-host temp.local --no-backupBackup Configuration
party.setup({
autoBackup: true, // Enable/disable auto-backup (default: true)
maxBackups: 10 // Maximum backups to keep (default: 10)
});Dry Run Mode
Preview changes before applying them:
$ hostparty add 127.0.0.1 test.local --dry-run
[DRY RUN] Would add: test.local -> 127.0.0.1
[DRY RUN] No changes written to disk.party.setup({ dryRun: true });
const result = await party.add('127.0.0.1', ['test.local']);
// { dryRun: true, message: 'Would add: test.local -> 127.0.0.1', preview: '...' }Protected Entries
Certain entries are protected from accidental removal as they're critical for OS networking. Attempting to remove these without the force flag will result in an error.
Protected IP Addresses
| IP | Purpose | OS |
|----|---------|-----|
| 127.0.0.1 | IPv4 loopback | All |
| ::1 | IPv6 loopback | All |
| fe80::1%lo0 | Link-local address | macOS |
| 255.255.255.255 | Broadcast address | macOS |
Protected Hostnames
| Hostname | Purpose | OS |
|----------|---------|-----|
| localhost | Loopback hostname | All |
| broadcasthost | Broadcast hostname | macOS |
Overriding Protection
Use the --force flag (CLI) or force: true option (API) to modify protected entries:
# CLI
hostparty remove-ip 127.0.0.1 --force
hostparty remove-host localhost --force// API
party.setup({ force: true }).removeIP('127.0.0.1');
party.setup({ force: true }).removeHost('localhost');Warning: Removing these entries can break networking on your system. Use with caution.
License
MIT
