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

@liftitinc/geocoding

v0.2.0

Published

JavaScript/TypeScript SDK for Liftit Geocoding API

Readme

@liftit/geocoding

npm version License Node version

JavaScript/TypeScript SDK for the Liftit Geocoding API.

Installation

npm install @liftit/geocoding
# or
pnpm add @liftit/geocoding
# or
yarn add @liftit/geocoding

Quick Start

import { GeocodingClient } from '@liftit/geocoding';

const client = new GeocodingClient({
  apiKey: 'your-api-key',
  // Optional configuration:
  // baseUrl: 'https://geocoding.liftit.co',
  // timeout: 10000,
  // maxRetries: 3,
});

// Forward geocoding - convert address to coordinates
const result = await client.geocode({
  country: 'co',
  city: 'Bogota',
  address: 'Calle 100 # 19-61',
  // Optional parameters:
  // region: 'Cundinamarca',
  // custom_zone: true,
});

console.log(result.location);        // { lat: 4.6097, lng: -74.0817 }
console.log(result.geocode.formatted_address);

// Reverse geocoding - convert coordinates to address
const address = await client.reverseGeocode({
  lat: 4.6097,
  lng: -74.0817,
});

console.log(address.geocode.formatted_address);
console.log(address.address_components?.city);

Features

  • TypeScript Support: Full type definitions with comprehensive type safety
  • Zero Dependencies: Uses native fetch API (Node.js 18+ required)
  • Automatic Retry: Exponential backoff with full jitter for transient errors
  • Rate Limit Handling: Respects Retry-After headers automatically
  • Error Hierarchy: Typed error classes for precise error handling
  • Zod Schemas: Exported schemas for request/response validation

Configuration

| Parameter | Type | Default | Description | |-----------|------|---------|-------------| | apiKey | string | Required | Your Liftit Geocoding API key | | baseUrl | string | "https://geocoding.liftit.co" | API base URL | | timeout | number | 10000 | Request timeout in milliseconds | | maxRetries | number | 3 | Maximum retry attempts for transient errors | | baseDelay | number | 1000 | Initial retry delay in milliseconds | | maxDelay | number | 30000 | Maximum retry delay cap in milliseconds |

Example:

const client = new GeocodingClient({
  apiKey: 'your-api-key',
  timeout: 15000,
  maxRetries: 5,
  baseDelay: 2000,
  maxDelay: 60000,
});

Retry Behavior

The SDK automatically retries requests for transient errors:

| Error Type | Retryable | Strategy | |------------|-----------|----------| | Rate limit (429) | Yes | Uses Retry-After header if present | | Server error (500, 502, 503, 504) | Yes | Exponential backoff with full jitter | | Timeout | Yes | Exponential backoff with full jitter | | Network errors | Yes | Exponential backoff with full jitter | | Validation (400) | No | Fails immediately | | Authentication (401) | No | Fails immediately | | User abort | No | Fails immediately |

Retry Timing

  • Initial delay: 1 second (configurable via baseDelay)
  • Maximum delay: 30 seconds (configurable via maxDelay)
  • Multiplier: 2x exponential growth
  • Jitter: Full random jitter (0 to calculated delay)
  • Default attempts: 3 retries (configurable via maxRetries)

Formula: delay = min(baseDelay * 2^attempt * random(), maxDelay)

Disabling Retries

// Disable retries for testing or special cases
const client = new GeocodingClient({
  apiKey: 'your-api-key',
  maxRetries: 0,
});

Error Handling

The SDK provides a comprehensive error hierarchy:

import {
  GeocodingClient,
  GeocodeError,
  ValidationError,
  AuthenticationError,
  RateLimitError,
  UpstreamError,
} from '@liftit/geocoding';

const client = new GeocodingClient({ apiKey: 'your-api-key' });

try {
  const result = await client.geocode({
    country: 'co',
    city: 'Bogota',
    address: 'Calle 100 # 19-61',
  });
} catch (error) {
  if (error instanceof ValidationError) {
    // Invalid request parameters (400)
    console.error(`Validation error: ${error.message}`);
    console.error(`Request ID: ${error.requestId}`);
  } else if (error instanceof AuthenticationError) {
    // Invalid API key (401)
    console.error(`Authentication failed: ${error.message}`);
  } else if (error instanceof RateLimitError) {
    // Rate limit exceeded (429)
    console.error(`Rate limited. Retry after ${error.retryAfter} seconds`);
    console.error(`Limit: ${error.limit}, Remaining: ${error.remaining}`);

    // Calculate optimal retry delay
    const delayMs = error.getRetryDelay();
    await new Promise(resolve => setTimeout(resolve, delayMs));
    // Retry request...
  } else if (error instanceof UpstreamError) {
    // API server error (500-599)
    console.error(`Upstream error: ${error.message}`);
    console.error(`Status code: ${error.statusCode}`);
  } else if (error instanceof GeocodeError) {
    // Base class catches all SDK errors
    console.error(`Geocoding error [${error.code}]: ${error.message}`);
  }
}

Error Properties:

| Error Class | Properties | |-------------|------------| | GeocodeError | message, code, requestId | | ValidationError | Inherits from GeocodeError | | AuthenticationError | Inherits from GeocodeError | | RateLimitError | Inherits + retryAfter, limit, remaining, getRetryDelay() | | UpstreamError | Inherits + statusCode |

API Reference

Forward Geocoding

Convert an address to geographic coordinates.

Method: client.geocode(request, options?)

Parameters:

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | request.country | string | Yes | ISO 3166-1 alpha-2 country code (ar, br, cl, co, ec, mx, pe) | | request.address | string | Yes | Street address to geocode | | request.city | string | No | City name (recommended for accuracy) | | request.region | string | No | State/department name | | request.custom_zone | boolean | No | Include zone information (default: false) | | options.signal | AbortSignal | No | AbortSignal for request cancellation |

Response:

{
  success: true,
  data: {
    location: { lat: number, lng: number },
    geocode: { formatted_address: string },
    cleaned_address: boolean,
    zone?: { id: number, name: string, type: string }
  },
  requestId: string
}

Example:

const result = await client.geocode({
  country: 'co',
  city: 'Bogota',
  address: 'Calle 100 # 19-61',
  custom_zone: true,
});

console.log(result.location);  // { lat: 4.6097, lng: -74.0817 }
console.log(result.zone?.name); // "Zone 1"

Reverse Geocoding

Convert geographic coordinates to an address.

Method: client.reverseGeocode(request, options?)

Parameters:

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | request.lat | number | Yes | Latitude (-90 to 90) | | request.lng | number | Yes | Longitude (-180 to 180) | | options.signal | AbortSignal | No | AbortSignal for request cancellation |

Response:

{
  success: true,
  data: {
    geocode: { formatted_address: string },
    location: { lat: number, lng: number },
    address_components: {
      city: string,
      country: string
    }
  },
  requestId: string
}

Example:

const address = await client.reverseGeocode({
  lat: 4.6097,
  lng: -74.0817,
});

console.log(address.geocode.formatted_address);
console.log(address.address_components?.city); // "Bogota"

Supported Countries

The SDK supports geocoding in the following countries:

| Country | Code | Example City | |---------|------|--------------| | Argentina | ar | Buenos Aires | | Brazil | br | Sao Paulo | | Chile | cl | Santiago | | Colombia | co | Bogota | | Ecuador | ec | Quito | | Mexico | mx | Mexico City | | Peru | pe | Lima |

Requirements

  • Node.js: >= 18.0.0 (required for native fetch API)
  • Runtime Dependencies: None (zero dependencies)
  • TypeScript: >= 5.0 (for TypeScript projects)

Development

# Clone the repository
git clone https://github.com/Liftitapp/geocoding-enterprise.git
cd geocoding-enterprise

# Install dependencies
pnpm install

# Build the SDK
pnpm --filter @liftit/geocoding build

# Run tests
pnpm --filter @liftit/geocoding test

# Type checking
pnpm --filter @liftit/geocoding typecheck

# Lint
pnpm --filter @liftit/geocoding lint

License

MIT - see LICENSE for details.

Support