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

@xenterprises/fastify-xgeocode

v1.2.1

Published

Fastify plugin for Geocodio API integration with address geocoding and reverse geocoding.

Readme

@xenterprises/fastify-xgeocode

Fastify plugin for Geocodio API integration — geocode addresses and ZIP codes, reverse-geocode coordinates, calculate distances, and validate addresses.

Installation

npm install @xenterprises/fastify-xgeocode

Quick Start

import Fastify from 'fastify';
import xGeocode from '@xenterprises/fastify-xgeocode';

const fastify = Fastify();

await fastify.register(xGeocode, {
  apiKey: process.env.GEOCODIO_API_KEY
});

fastify.get('/location/:zip', async (request) => {
  return fastify.xGeocode.getLatLongByZip(request.params.zip);
});

await fastify.listen({ port: 3000 });

Options

| Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | apiKey | string | — | Yes | Geocodio API key | | active | boolean | true | No | Set to false to skip plugin registration entirely | | fields | string | 'cd,stateleg' | No | Comma-separated Geocodio fields to include (e.g. 'timezone,census,cd') |

Decorated Properties

The plugin decorates the Fastify instance with fastify.xGeocode, which exposes:

getLatLongByZip(zipCode)

Geocode a US ZIP code (5-digit or ZIP+4 format).

const result = await fastify.xGeocode.getLatLongByZip('10001');
// { zip, lat, lng, formatted_address, city, county, state, country, addressComponents }

getLatLongByAddress(address)

Geocode a street address.

const result = await fastify.xGeocode.getLatLongByAddress('1600 Pennsylvania Ave NW, Washington DC');
// { lat, lng, formatted_address, city, county, state, country, zip, addressComponents }

getReverseGeocode(lat, lng)

Get an address from latitude/longitude coordinates.

const result = await fastify.xGeocode.getReverseGeocode(40.7128, -74.0060);
// { lat, lng, formatted_address, city, county, state, country, zip, addressComponents }

getDistance(lat1, lng1, lat2, lng2)

Calculate the distance between two geographic points using the Haversine formula. This is a synchronous method — no API call is made.

const distance = fastify.xGeocode.getDistance(40.7128, -74.0060, 34.0522, -118.2437);
// { kilometers: 3944.42, miles: 2451.21, meters: 3944422 }

batchGeocode(locations)

Geocode up to 100 addresses or ZIP codes in a single call. Each item is geocoded individually; failures are returned inline without throwing.

const results = await fastify.xGeocode.batchGeocode([
  '10001',
  '1600 Pennsylvania Ave NW, Washington DC',
  'invalid address'
]);
// [
//   { zip: '10001', lat: 40.75, lng: -73.99, ... },
//   { original: '1600 Pennsylvania...', lat: 38.89, lng: -77.03, ... },
//   { original: 'invalid address', error: '...', success: false }
// ]

validateAddress(address)

Validate an address and get its standardized form. Does not throw on unrecognized addresses — returns { valid: false } instead.

const result = await fastify.xGeocode.validateAddress('123 Main St');
// { valid: true, input: '123 Main St', formatted: '123 Main Street, ...', confidence: 'rooftop', lat, lng, ... }

const bad = await fastify.xGeocode.validateAddress('zzzzz nowhere');
// { valid: false, input: 'zzzzz nowhere', error: 'Address not recognized' }

Environment Variables

| Name | Required | Description | |------|----------|-------------| | GEOCODIO_API_KEY | Yes | API key from geocod.io |

Error Reference

All errors are prefixed with [xGeocode] for easy filtering.

| Error | When | |-------|------| | [xGeocode] apiKey is required in options | Plugin registered without an API key | | [xGeocode] apiKey must be a string | API key is not a string | | [xGeocode] fields must be a string | fields option is not a string | | [xGeocode] Invalid input - zipCode must be a non-empty string | getLatLongByZip called with null/undefined/non-string | | [xGeocode] Invalid zip code format | ZIP code doesn't match 5-digit or ZIP+4 format | | [xGeocode] Invalid input - address must be a non-empty string | Address methods called with null/undefined/non-string | | [xGeocode] Invalid address - minimum 3 characters required | Address is shorter than 3 characters | | [xGeocode] Invalid coordinates - latitude and longitude must be numbers | Non-numeric coordinates provided | | [xGeocode] Invalid latitude - must be between -90 and 90 | Latitude out of range | | [xGeocode] Invalid longitude - must be between -180 and 180 | Longitude out of range | | [xGeocode] No results found | Geocodio returned no matching results | | [xGeocode] Geocoding API returned {status} | Geocodio API returned a non-2xx status | | [xGeocode] locations must be an array | batchGeocode called with non-array | | [xGeocode] locations array cannot be empty | batchGeocode called with empty array | | [xGeocode] batch size cannot exceed 100 locations | batchGeocode called with >100 items |

How It Works

The plugin wraps the Geocodio REST API v1.7. On registration, it validates the provided options and decorates the Fastify instance with an xGeocode object containing six methods.

  • Forward geocoding (getLatLongByZip, getLatLongByAddress) sends a GET request to https://api.geocod.io/v1.7/geocode with the address or ZIP as the q parameter and returns the first result's coordinates and address components.
  • Reverse geocoding (getReverseGeocode) sends a GET to the /reverse endpoint with comma-separated lat/lng.
  • Distance (getDistance) uses the Haversine formula locally — no API call is made.
  • Batch (batchGeocode) runs individual geocode calls in parallel via Promise.all, returning results inline. Failed items include { success: false, error } instead of throwing.
  • Validation (validateAddress) geocodes the address and wraps the result with valid: true/false and a confidence score from Geocodio's accuracy field.

The fields option controls which supplementary data Geocodio returns (congressional districts, state legislative districts, timezone, census data, etc.). See the Geocodio fields documentation for available values.

License

UNLICENSED