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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@trap_stevo/geotide

v0.0.2

Published

Fuses IP intelligence, reverse geocoding, and radio/Wi-Fi triangulation into a single, real-time, precision-crafted API. Trace a single packet’s origin, map a million connections, or power real-time location-aware apps with elegance, accuracy, and streami

Readme

🌊 @trap_stevo/geotide

The ultimate event-driven, precision-powered geolocation engine — from IP to doorstep, in real-time.
Fuses IP intelligence, reverse geocoding, and radio/Wi-Fi triangulation into a single, real-time, precision-crafted API.
Trace a single packet’s origin, map a million connections, or power real-time location-aware apps with elegance, accuracy, and streaming insight.


🚀 Features

  • 🌍 Multi-Provider IP Intelligence – Auto-races top geo APIs (ipwhois, ipapi, ipinfo, ipgeolocation) with scoring and failover
  • 🛰 Reverse Geocoding – Converts coordinates to human-readable addresses
  • Real-Time Event System – Subscribe to lookups, cache hits, provider health, and reverse-geocoding events as they happen
  • 🧩 Custom Provider Injection – Append your own IP lookup, reverse geocoding, or triangulation services
  • 📦 Batch Mode – Resolve thousands of IPs at once with bounded concurrency and preserved order
  • 🛡 Resilient & Cached – LRU caching and automatic provider failover for speed and reliability
  • 🔍 Confidence Scoring – Each lookup is scored for trustworthiness

🧠 Use Cases

  • Live geolocation dashboards
  • Security and fraud prevention
  • Multiplayer game region detection
  • Content localization and targeting
  • Network monitoring and analytics
  • Emergency response systems

⚙️ System Requirements

| Requirement | Version | |----------------|----------------------| | Node.js | ≥ 19.x | | npm | ≥ 9.x (recommended) | | OS | Windows, macOS, Linux|


🔍 API Specifications

🔧 Methods

| Method | Signature | Returns | Description | Async? | |---|---|---|---|---| | lookup(ip) | lookup(ip: string) | Promise<GeoResult \| null> | Resolves a public IP into normalized location metadata. Uses provider race + scoring + TTL cache. | Yes | | lookupMany(ips, opts?) | lookupMany(ips: string[], opts?: { concurrency?: number }) | Promise<(GeoResult \| null)[]> | Batch IP lookup with bounded concurrency (default = maxConcurrency). | Yes | | reverse(lat, lon, opts?) | reverse(lat: number, lon: number, opts?: { deadlineMs?: number, cacheTtlMs?: number }) | Promise<ReverseResult \| null> | Reverse-geocodes coordinates to a human address by racing Mapbox/Google/Nominatim with caching. | Yes | | getClientIP(req) | getClientIP(req: IncomingMessage \| Express.Request) | string \| null | Extracts the client's IP from HTTP request headers and connection info, supporting proxies and IPv6 normalization. | No | | on(event, handler) | on(event: GeoTideEvent, handler: (payload: any) => void) | this | Subscribe to real-time events (telemetry, results, cache hits, health). | No | | off(event, handler) | off(event: GeoTideEvent, handler: Function) | this | Unsubscribe a previously registered listener. | No |


📦 Return Types

type GeoResult = {
  source: string;              // provider name
  ip: string;
  city: string | null;
  region: string | null;
  country: string | null;
  org: string | null;
  isp: string | null;
  loc: string | null;          // "lat,lon"
  timezone: string | null;
  postal: string | null;
  flag: string | null;         // emoji when available
  continent: string | null;
  confidence: number;          // 0..1
};

type ReverseResult = {
  provider: string;            // provider name
  formatted: string;
  components: any;
  lat: number;
  lon: number;
};

📡 Events

| Event | Payload | Description | |---|---|---| | lookup:start | { ip } | A lookup has started. | | lookup:cache_hit | { ip, result } | Result served from cache. | | lookup:result | { ip, result } | Fresh lookup result returned. | | provider:success | { provider, ip, durationMs, score } | A provider returned data successfully. | | provider:fail | { provider, ip, error } | A provider failed. | | provider:unhealthy | { provider, reason } | Provider marked temporarily unhealthy. | | reverse:start | { lat, lon } | Reverse geocoding started. | | reverse:cache_hit | { lat, lon, result } | Reverse geocoding served from cache. | | reverse:result | { lat, lon, result } | Fresh reverse geocoding result returned. |


📦 Installation

npm install @trap_stevo/geotide

🛠️ Usage

🌐 IP Lookup

const GeoTide = require("@trap_stevo/geotide");

const geo = new GeoTide({ enableGeoDebug : true });

const result = await geo.lookup("203.0.113.42");

console.log(result);
// {
//   source: 'ipwhois',
//   ip: '203.0.113.42',
//   city: 'Sample City',
//   region: 'Sample Region',
//   country: 'Sample Country',
//   org: 'Sample ISP Org',
//   isp: 'Sample ISP',
//   loc: '37.4221,-122.0841',
//   timezone: 'America/Los_Angeles',
//   postal: '94043',
//   flag: '🌍',
//   continent: 'North America',
//   confidence: 1
// }

📦 Batch IP Lookup

const results = await geo.lookupMany([
  "203.0.113.42",
  "8.8.8.8"
]);

console.log(results);

🗺 Reverse Geocoding

const address = await geo.reverse(40.712776, -74.005974);

console.log(address.formatted);
// "Example Building, 123 Example Street, Sample City, NY, United States"

⚡ Real-Time Events

geo.on("lookup:result", ({ ip, result }) => {
  console.log(`[GeoTide] ${ip} → ${result.city}, ${result.country}`);
});

📜 License

See License in LICENSE.md


🌊 GeoTide — The Pulse of the Planet, in Real-Time.
From the ocean of IPs to the pinpoint of a doorstep, GeoTide flows with accuracy, speed, and live awareness.