npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

hostparty

v2.1.0

Published

Programmatic and CLI editing for OS hosts file

Readme

hostparty

npm version

Cross-platform CLI and JavaScript API for managing your hosts file.

Installation

# CLI usage
npm install -g hostparty

# Library usage
npm install hostparty

Quick 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 it

CommonJS

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.local

party.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.local

party.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-000Z

party.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 version

Examples

# 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-backup

Smart 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.100

Backup & 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-backup

Backup 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