🌊 @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
Node.js | ≥ 19.x |
npm | ≥ 9.x (recommended) |
OS | Windows, macOS, Linux |
🔍 API Specifications
🔧 Methods
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;
ip: string;
city: string | null;
region: string | null;
country: string | null;
org: string | null;
isp: string | null;
loc: string | null;
timezone: string | null;
postal: string | null;
flag: string | null;
continent: string | null;
confidence: number;
};
type ReverseResult = {
provider: string;
formatted: string;
components: any;
lat: number;
lon: number;
};
📡 Events
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);
📦 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);
⚡ 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.