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

@smarthivelabs-devs/geocore-node

v1.6.5

Published

Geocore Node.js server SDK — mapping and geocoding for backend services

Readme

@smarthivelabs-devs/geocore-node

Node.js / server-side SDK for Geocore. Lightweight HTTP client — no browser dependencies. Covers all 14 geo-operations, weather, the SmartHive Pricing Engine, and two new Location Intelligence operations built for delivery and logistics apps.

Installation

npm install @smarthivelabs-devs/geocore-node
# or
pnpm add @smarthivelabs-devs/geocore-node

Requires Node.js 18+ (uses native fetch and AbortSignal.timeout).


Setup

import { GeocoreNodeClient } from '@smarthivelabs-devs/geocore-node';

const geocore = new GeocoreNodeClient({
  apiKey: process.env.GEOCORE_API_KEY!,
  // baseUrl — optional, defaults to https://geocore.smarthivelabs.dev/api
  // timeout — optional, default 8000 ms
});

GeocoreNodeClientConfig

| Field | Type | Required | Description | |-------|------|----------|-------------| | apiKey | string | Yes | Your Geocore project API key (x-api-key header) | | baseUrl | string | No | Override backend URL — defaults to production | | timeout | number | No | Request timeout in ms — default 8000 |


Geocoding

// Address → coordinates
const result = await geocore.geocode('Kaneshie Market, Accra');
console.log(result.coordinates); // { lat: 5.5558, lng: -0.2318 }
console.log(result.provider);    // 'mapbox'

// Coordinates → address
const rev = await geocore.reverse(5.5558, -0.2318);
console.log(rev.formattedAddress);

Location Intelligence ✨

Two new operations designed for logistics and delivery apps — where a wrong-city geocode costs money.

geocodeMulti — all-provider fan-out

Returns every unique candidate from all configured providers simultaneously, deduplicated by 200 m proximity. Use this when you need a diverse result set to score or rank downstream.

const result = await geocore.geocodeMulti('Calabash Restaurant', { limit: 12 });
// result.results — GeocodingResult[] from Mapbox, Google, LocationIQ, HERE, …
// result.provider — 'multi'
// result.status   — 'ok' | 'zero_results'

for (const candidate of result.results) {
  console.log(`${candidate.provider}: ${candidate.formattedAddress}`);
  // mapbox: Calabash Restaurant, Kumasi, Ghana
  // google: Calabash, Accra, Ghana
  // locationiq: Calabash Cafe, Takoradi, Ghana
}

resolveLocation — delivery-grade smart resolution

Accepts a structured LocationIntent and returns scored, ranked candidates with a deterministic resolution state. Prevents silent wrong-city dispatches common in logistics apps — e.g. "Calabash near St. Teresa's in Kumasi" should never silently resolve to "Kalabash Cyber Cafe, Accra".

7-step algorithm:

  1. Generate up to 8 query variants (name, +city, +area, +type, multi-city fan-out, near landmark)
  2. Fan-out geocode across all providers → collect raw candidates
  3. Geocode landmarks and build a geospatial cluster (centroid + radius)
  4. Score each candidate on 7 dimensions (see weights below)
  5. Apply mismatch penalties
  6. Determine resolution state: exact / probable / approximate / unresolved
  7. Detect multi-city ambiguity for disambiguation UI

Score weights: name similarity 30% · landmark consistency 25% · city/area match 15% · place type 10% · provider confidence 10% · user proximity 5% · place memory 5%

Mismatch penalties: city mismatch −0.40 · landmark >50 km −0.35 · weak name −0.25 · area mismatch −0.20 · wrong type −0.10

import type { LocationIntent, ResolveLocationOptions } from '@smarthivelabs-devs/geocore-node';

const intent: LocationIntent = {
  main_place_name: 'Calabash',
  landmarks: ["St. Teresa's Hostel"],
  city: 'Kumasi',
  place_type: 'restaurant',
  normalized_queries: ['Calabash Restaurant Kumasi'],
};

const options: ResolveLocationOptions = {
  proximity: { lat: 6.6884, lng: -1.6244 }, // user's current location
};

const result = await geocore.resolveLocation(intent, options);

console.log(result.state);               // 'exact'
console.log(result.requires_confirmation); // false
console.log(result.explanation);
// "Found Calabash Restaurant, Kumasi, consistent with nearby St. Teresa's Hostel."

const best = result.selected_candidate!;
console.log(best.lat, best.lng);         // 6.688..., -1.624...
console.log(best.score);                 // 0.91
console.log(best.mismatchFlags);         // []

// When state is 'approximate' or 'unresolved', show ranked_candidates in UI
for (const c of result.ranked_candidates) {
  console.log(`${c.score.toFixed(2)} — ${c.formatted} [${c.city}]`);
}

// Multi-city disambiguation (show "Which Calabash?" UI)
if (result.multi_city_disambiguation) {
  const cities = [...new Set(result.ranked_candidates.map(c => c.city))];
  console.log('Ambiguous cities:', cities); // ['Kumasi', 'Accra', 'Takoradi']
}

Resolution states

| State | Meaning | requires_confirmation | |---|---|:---:| | exact | High confidence, no severe flags | false | | probable | Good score, no severe flags — show for user confirmation | true | | approximate | Low score but landmark cluster exists — show options | true | | unresolved | Could not resolve — show map pin / manual entry | true |

Handling place memory bias

Pass userPlaceHistory to boost candidates near places the user has previously confirmed. This is the only app-specific dimension — omit it if you don't have history.

const result = await geocore.resolveLocation(intent, {
  proximity: { lat: 6.69, lng: -1.62 },
  userPlaceHistory: [
    { label: 'Office', lat: 6.6884, lng: -1.6244, useCount: 12 },
    { label: 'Gym', lat: 6.6720, lng: -1.5980, useCount: 3 },
  ],
});

Directions & Routing

// Turn-by-turn directions
// mode: 'driving' | 'walking' | 'cycling' | 'transit'
const route = await geocore.directions(
  { lat: 5.5558, lng: -0.2318 },
  { lat: 5.6037, lng: -0.1870 },
  { mode: 'driving' }
);
console.log(route.distance); // metres
console.log(route.duration); // seconds
console.log(route.steps);    // turn-by-turn instructions

// Optimise waypoint order (Travelling Salesman)
const optimised = await geocore.routeOptimize(
  ['Accra Mall', 'Airport City, Accra', 'Tema, Ghana'],
  { mode: 'driving' }
);
console.log(optimised.waypoints); // reordered array

// Snap GPS trace to road network
const snapped = await geocore.snapToRoad([
  { lat: 5.556, lng: -0.232 },
  { lat: 5.558, lng: -0.231 },
]);
console.log(snapped.snappedPoints);

Places & Search

// Text search — radius in metres (optional)
const places = await geocore.places('pharmacy', { lat: 5.556, lng: -0.232 }, { radius: 500 });
console.log(places.places); // [{ name, coordinates, address, rating, types }]

// Category search around a point
const nearby = await geocore.nearbySearch('hospital', { lat: 5.556, lng: -0.232 });
console.log(nearby.places);

// Autocomplete predictions
const suggest = await geocore.autocomplete('Accra Mall');
console.log(suggest.predictions); // [{ mainText, secondaryText, placeId }]

Spatial Analysis

// Elevation
const elev = await geocore.elevation(6.6884, -1.6244);
console.log(elev.elevation); // metres

// Isochrone (reachability polygon)
const iso = await geocore.isochrone(6.6884, -1.6244, [10, 20], { mode: 'driving' });
console.log(iso.polygons); // array of GeoJSON polygons per time band

// Distance matrix
const matrix = await geocore.distanceMatrix(
  ['Accra, Ghana', 'Kumasi, Ghana'],
  ['Tema, Ghana', 'Cape Coast, Ghana'],
);
console.log(matrix.matrix); // [[{distance, duration}, …], …]

// Timezone
const tz = await geocore.timezone(6.6884, -1.6244);
console.log(tz.timezone); // 'Africa/Accra'

// Traffic conditions
const traffic = await geocore.traffic(5.556, -0.232);
console.log(traffic.condition); // 'free' | 'slow' | 'heavy' | 'blocked'

// Static map image URL
const map = await geocore.staticMap(5.556, -0.232, { zoom: 14, width: 800, height: 600 });
console.log(map.url);

Weather

// Current conditions
const now = await geocore.weather(6.6884, -1.6244);
console.log(now.temperature);   // °C
console.log(now.weatherCode);   // WMO code (map to your condition enum)
console.log(now.description);   // 'Partly cloudy'
console.log(now.humidity);      // %
console.log(now.windSpeed);     // km/h

// Forecast (1–14 days, default 7)
const forecast = await geocore.forecast(6.6884, -1.6244, 5);
for (const day of forecast.days ?? []) {
  console.log(`${day.date}: ${day.tempMin}–${day.tempMax}°C — ${day.description}`);
}

SmartHive Pricing Engine

Convert a base price to any user's local currency based on their location or country code. Exchange rates are refreshed by the Geocore backend on the 1st and 15th of each month.

// Auto-detect user's country from lat/lng
const price = await geocore.localizePrice(100, 'GHS', {
  lat: 6.5244,   // user in Lagos, Nigeria
  lng: 3.3792,
});
// { amount: 4500, currency: 'NGN', symbol: '₦', country: 'NG', rate: 45.0, ... }

// Manual country override
const usd = await geocore.localizePrice(100, 'GHS', { countryCode: 'US' });
// { amount: 9.99, currency: 'USD', symbol: '$', ... }

// FX rate pairs
const rate = await geocore.fxRate('USD', 'EUR');
const rates = await geocore.fxRates('USD'); // all rates for a base

Provider Registry

const providers = await geocore.getProviders();
const mapbox = await geocore.getProvider('mapbox');
const geocoders = await geocore.getProvidersForOperation('geocode');

Error Handling

All methods throw Error when the request fails or all providers are exhausted.

try {
  const result = await geocore.geocode('Unknown XYZ');
} catch (err) {
  if (err instanceof Error) {
    console.error(err.message);
    // 'API error 404: Not Found'
    // 'All providers failed for geocode. mapbox: ...'
  }
}

Requests automatically abort after timeout ms (default 8000).


TypeScript

All methods and responses are fully typed. Import the types you need:

import type {
  // Standard geo
  GeocodingResult, ReverseGeocodingResult,
  DirectionsResult, RouteOptimizeResult, SnapToRoadResult,
  PlacesResult, NearbySearchResult, AutocompleteResult,
  ElevationResult, IsochroneResult, TimezoneResult,
  DistanceMatrixResult, TrafficResult, StaticMapResult,
  // Weather
  WeatherCurrentResult, WeatherForecastResult,
  // Pricing
  PricingResult, FxRateResult, FxRatesResult,
  // Location intelligence
  LocationIntent, ResolveLocationOptions,
  LocationResolutionResult, LocationResolutionState,
  LocationMismatchFlag, RankedLocationCandidate,
  ValidatedLandmark, LandmarkClusterSummary,
  PlaceMemoryRecord, GeocodingMultiResult,
} from '@smarthivelabs-devs/geocore-node';

License

MIT — SmartHive Labs