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

zipcode-neighbors

v2.2.2

Published

Find neighboring postal code areas using GeoJSON boundary data and spatial analysis. Prepacked with Berlin, Germany. Configurable to other localities.

Readme

Berlin ZIP Code Neighbor Finder

A Node.js module to find neighboring postal code areas in Berlin using GeoJSON boundary data and spatial analysis.

Overview

This module provides a way to identify which Berlin postal codes share geographic boundaries with each other. It includes pre-computed mappings for fast lookups with automatic fallback to geometric computation.

It utilizes geodata from yetzt's wonderful postleitzahlen project. Check it out!

Features

  • Fast cached lookups: Pre-computed mappings for instant neighbor queries (O(1) lookup)
  • Geographic neighbor detection: Find all postal codes that share a boundary with a given ZIP code
  • Berlin-default: Pre-filtered dataset containing only Berlin postal codes but pipeline to add custom localities
  • Fallback computation: Automatically computes neighbors if cache is unavailable
  • Efficient spatial analysis: Uses Turf.js for geometric operations
  • CLI tool: Includes command-line interface for quick lookups
  • NPM installable: Install as a dependency in your projects

Installation

From GitHub (using npm)

npm install github:machinaeXphilip/zipcode-neighbors

Or via git URL:

npm install git+https://github.com/machinaeXphilip/zipcode-neighbors.git

From NPM Registry

install via:

npm install zipcode-neighbors

Usage

As a Module

Import and use the module in your JavaScript code:

//import { findNeighbors } from './lib/index.js'; // if you downloaded the source
import { findNeighbors } from 'zipcode-neighbors'; // if you installed via package manager

// Find neighboring postal codes for 13156 (uses Berlin by default)
const neighbors1 = findNeighbors('13156');
console.log(neighbors1); // ['12627', '13155', '14165', ...]

// Force recomputation from features (slower, but always works)
const neighbors2 = findNeighbors('13156', false, true);

// Show progress during computation
const neighbors3 = findNeighbors('13156', true, false);

console.log(neighbors1, neighbors2, neighbors3)

Using Different Localities

To use a different locality, set the LOCALITY environment variable before importing (only possible if you've prepared data for other localities as described below):

process.env.ZIPCODE_DATA_DIR = './my-zipcode-data';
process.env.LOCALITY = 'dusseldorf';

const { findNeighbors } =  import('zipcode-neighbors');
const neighbors = findNeighbors('40210');

API

findNeighbors(targetZip, showProgress, forceCompute)

Find neighboring postal codes for a given Berlin ZIP code.

Parameters:

  • targetZip (string): The postal code to find neighbors for
  • showProgress (boolean, optional): Whether to show progress logs during computation (default: false)
  • forceCompute (boolean, optional): Force computation from features instead of using cache (default: false)

Returns:

  • Array of neighboring postal codes, sorted alphabetically

findNeighborsFromFeatures(targetZip, showProgress)

Find neighbors by computing from GeoJSON features (slower method, always works).

Parameters:

  • targetZip (string): The postal code to find neighbors for
  • showProgress (boolean, optional): Whether to show progress logs (default: false)

Returns:

  • Array of neighboring postal codes, sorted alphabetically

loadNeighborMappings()

Manually load pre-computed neighbor mappings from disk. This is typically called automatically.

Command Line Interface

Use the included CLI tool to query neighbors directly:

# Download and install globally
npm install -g zipcode-neighbors

# Query for neighbors
zipcode-neighbors 13156

# Force computation instead of using cache
zipcode-neighbors 13156 true

Or use it with npx:

npx zipcode-neighbors 13156

Project Structure

.
├── lib/
│   └── index.js                           # Main module entry point
├── bin/
│   └── zipcode-neighbors.js               # CLI tool
├── data/
│   ├── postleitzahlen.geojson             # Decompressed source data
│   ├── postleitzahlen.geojson.br          # Brotli-compressed source data
│   └── localities/
│       ├── berlin/
│       │   ├── zipcodeList.json           # List of Berlin postal codes
│       │   ├── zipcodes.geojson           # GeoJSON data for Berlin postal codes
│       │   └── neighborMappings.json      # Pre-computed neighbor mappings (optional)
│       └── [other-localities]/            # Support for other localities
├── scripts/
│   ├── decompressFromBrotli.js
│   ├── filterPostcodesByList.js
│   └── generateNeighborMappings.js
├── test/
│   └── data-preparation-pipeline.test.js  # Integration tests for data pipeline
├── examples.js                             # Usage examples
├── package.json
├── LICENSE                                 # MIT License
├── DATA_LICENSE                            # ODbL data license
└── README.md

Prerequisites

  • Node.js (v18 or higher)
  • npm

Local Development

Install dependencies:

npm install

This will install:

  • @turf/turf - For spatial analysis operations
  • brotli - For decompressing source data

Cache Management

Each locality has its own cache file at <data-dir>/localities/<locality>/neighborMappings.json. By default, this is data/localities/<locality>/neighborMappings.json in the package directory, but when using custom data paths via ZIPCODE_DATA_DIR, it follows your custom location.

The module automatically uses this cache for instant lookups, with automatic fallback to geometric computation if the cache is unavailable.

Performance

  • Cached query: ~instant (JSON object lookup)
  • Without cache: ~slower per query depending on the size of the areas covered (geometric computation)

Data Preparation

The Berlin ZIP code data is already prepared and ready to use. However, you can update or add new localities using the data preparation pipeline.

Environment Variables

The scripts support two environment variables for configuration:

  • LOCALITY - Which locality to use (default: berlin). Set this when working with other localities
  • ZIPCODE_DATA_DIR - Base directory for all data files (default: <package>/data)

All file paths follow a predictable structure:

  • Source data: ${ZIPCODE_DATA_DIR}/postleitzahlen.geojson.br and postleitzahlen.geojson
  • Postcode lists: ${ZIPCODE_DATA_DIR}/localities/${LOCALITY}/zipcodeList.json
  • Locality output: ${ZIPCODE_DATA_DIR}/localities/${LOCALITY}/

Working from Source Repository

If you cloned this repository:

Step 1: Download Source Data

curl -L https://github.com/yetzt/postleitzahlen/releases/download/2026.02/postleitzahlen.geojson.br -o ./data/postleitzahlen.geojson.br

Step 2: Decompress the Data

node scripts/decompressFromBrotli.js

This reads data/postleitzahlen.geojson.br and creates data/postleitzahlen.geojson.

Step 3: Filter Postal Codes by Locality

For Berlin (default):

node scripts/filterPostcodesByList.js

For a different locality, set the LOCALITY environment variable (or pass it as a CLI argument):

LOCALITY=dusseldorf node scripts/filterPostcodesByList.js

# alternative w/o env
# node scripts/filterPostcodesByList.js ./data/localities/dusseldorf/zipcodeList.json

Note: You must first create the postcode list file (e.g., ./data/localities/dusseldorf/zipcodeList.json) with your desired postal codes before running this script.

Step 4 (Optional): Generate Neighbor Mappings Cache

For Berlin (default):

node scripts/generateNeighborMappings.js

For a different locality, set the LOCALITY environment variable (or pass it as a CLI argument fallback):

LOCALITY=dusseldorf node scripts/generateNeighborMappings.js

Note: This step is computationally intensive and may take several minutes.

Working with NPM-Installed Package

If you installed via npm and want to work with custom localities outside of node_modules:

Step 1: Set Up Custom Data Directory

mkdir -p my-zipcode-data/localities

Step 2: Download Source Data

curl -L https://github.com/yetzt/postleitzahlen/releases/download/2026.02/postleitzahlen.geojson.br -o my-zipcode-data/postleitzahlen.geojson.br

Step 3: Decompress the Data

ZIPCODE_DATA_DIR=./my-zipcode-data node node_modules/zipcode-neighbors/scripts/decompressFromBrotli.js

Step 4: Create Postcode List

Create your custom postcode list (array of strings or object with name and postcodes):

[
  "40210", "40211", "40212", "40213", "40215", "40217", "40219", "40221", "40223", "40225", "40227", "40229", "40231", "40233", "40235", "40237", "40239",
  "40468", "40470", "40472", "40474", "40476", "40477", "40479", "40489",
  "40545", "40547", "40549", "40589", "40591", "40593", "40595", "40597", "40599",
  "40625", "40627", "40629"
]

Step 5: Filter for Your Locality

ZIPCODE_DATA_DIR=./my-zipcode-data LOCALITY=dusseldorf node node_modules/zipcode-neighbors/scripts/filterPostcodesByList.js

Step 6 (Optional): Generate Neighbor Mappings

ZIPCODE_DATA_DIR=./my-zipcode-data LOCALITY=dusseldorf node node_modules/zipcode-neighbors/scripts/generateNeighborMappings.js

See the "Using Different Localities" section above for instructions on using your custom locality in code.

Example CLI Output

Finding neighbors for zip code 13127...
Neighboring zip codes: 13125, 13129, 13156, 13159
Total neighbors: 4
Time taken: 0.0023 seconds

How It Works

The neighbor detection uses the Turf.js library for spatial analysis:

  1. Loads the GeoJSON file containing Berlin postal code area boundaries
  2. For each comparison:
    • Uses turf.booleanTouches() to check if two polygons share a boundary
    • Two ZIP codes are considered neighbors if their boundaries touch
  3. Returns a sorted list of all neighboring postal codes

Data Source

The source data comes from the yetzt/postleitzahlen repository, which provides German postal code boundaries as GeoJSON.

Berlin Postal Codes

The dataset includes all Berlin postal codes ranging from:

  • 10115 - 10999 (Central Berlin)
  • 12043 - 12689 (South Berlin)
  • 13051 - 13629 (East Berlin)
  • 14050 - 14199 (West Berlin)

Total: ~190 postal code areas

License

Code License

This project code is licensed under the MIT License. See LICENSE.

Data License and Attribution

The GeoJSON data is derived from yetzt/postleitzahlen and is licensed under the ODC Open Database License (ODbL) v1.0. See DATA_LICENSE for full attribution and license requirements.

Mixed License Distribution (Important)

This package distributes mixed-licensed contents:

  • Code files (for example lib/, bin/, scripts/, examples.js) are under MIT.
  • Included dataset files under data/localities/ are under ODbL v1.0.

When redistributing this package, included data, or adapted database outputs derived from the included data, ensure you follow ODbL attribution and share-alike requirements in addition to the MIT terms for code.