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

flatgeographbuf

v1.1.0

Published

A performant binary encoding for geospatial graphs, extending FlatGeobuf with adjacency list support

Readme

FlatGeoGraphBuf

A performant binary encoding for geospatial graphs, extending FlatGeobuf with adjacency list support.

Features

  • Full FlatGeobuf compatibility for vertex/feature data
  • Efficient binary encoding for graph edges with arbitrary properties
  • TypeScript implementation optimized for decode performance
  • Streaming support for large graphs
  • Backward compatible - new properties don't break old readers
  • Compatible with NPM graph libraries (graphology, ngraph, cytoscape, etc.)

Installation

npm install flatgeographbuf

Usage

Encoding

import { serialize } from 'flatgeographbuf/geojson';

const geojson = {
    type: 'FeatureCollection',
    features: [
        { type: 'Feature', geometry: { type: 'Point', coordinates: [0, 0] }, properties: { name: 'A' } },
        { type: 'Feature', geometry: { type: 'Point', coordinates: [1, 1] }, properties: { name: 'B' } },
        { type: 'Feature', geometry: { type: 'Point', coordinates: [2, 2] }, properties: { name: 'C' } },
    ]
};

const adjacencyList = {
    edges: [
        { from: 0, to: 1, properties: { weight: 1.5, road_type: 'highway' } },
        { from: 1, to: 2, properties: { weight: 2.0, road_type: 'local' } },
    ]
};

const bytes = serialize(geojson, adjacencyList);

Decoding

import { deserialize } from 'flatgeographbuf/geojson';

const result = await deserialize(bytes);

console.log(result.features);      // GeoJSON features (vertices)
console.log(result.adjacencyList); // { edges: [...] }

Streaming Edges

import { deserializeGraphEdges } from 'flatgeographbuf/geojson';

for await (const edge of deserializeGraphEdges(bytes)) {
    console.log(`Edge from ${edge.from} to ${edge.to}`);
}

API

Types

interface EdgeInput {
    from: number;
    to: number;
    properties?: EdgeProperties;  // Optional on input
}

interface Edge {
    from: number;
    to: number;
    properties: EdgeProperties;   // Always present on output (empty {} if none)
}

interface EdgeProperties {
    [key: string]: boolean | number | string | object | Uint8Array;
}

interface AdjacencyListInput {
    edges: EdgeInput[];
}

interface AdjacencyList {
    edges: Edge[];
}

interface DeserializeGraphResult<T> {
    features: T[];
    adjacencyList: AdjacencyList;
}

interface FeaturesHeaderMeta {
    featuresCount: number;
    columns: ColumnMeta[] | null;
    geometryType: GeometryType;
    envelope: Float64Array | null;
    indexNodeSize: number;
    crs: CrsMeta | null;
    title: string | null;
    description: string | null;
    metadata: string | null;
}

interface GraphHeaderMeta {
    edgeCount: number;
    edgeColumns: ColumnMeta[] | null;
}

interface FlatGeoGraphBufMeta {
    features: FeaturesHeaderMeta;
    graph: GraphHeaderMeta | null;
}

type FlatGeoGraphBufMetaFn = (meta: FlatGeoGraphBufMeta) => void;

Functions

serialize(geojson, adjacencyList?, crsCode?): Uint8Array

Serialize GeoJSON features and optional graph edges to FlatGeoGraphBuf format.

  • geojson - GeoJSON FeatureCollection (vertices)
  • adjacencyList - Optional graph edges with properties
  • crsCode - Optional CRS code (default: 0)

deserialize(bytes, metaFn?): Promise<DeserializeGraphResult>

Deserialize FlatGeoGraphBuf to features and adjacency list.

  • bytes - FlatGeoGraphBuf binary data
  • metaFn - Optional callback receiving combined feature and graph metadata
await deserialize(bytes, (meta) => {
    // Feature metadata (nested under 'features')
    console.log(meta.features.featuresCount);  // number of features
    console.log(meta.features.columns);        // ColumnMeta[] - feature property schema
    
    // Graph metadata (null if no graph section)
    if (meta.graph) {
        console.log(meta.graph.edgeCount);     // number of edges
        console.log(meta.graph.edgeColumns);   // ColumnMeta[] - edge property schema
    }
});

deserializeStream(input, rect?, headerMetaFn?): AsyncGenerator<Feature>

Streaming deserialize features only.

  • input - Uint8Array or ReadableStream
  • rect - Optional bounding box filter
  • headerMetaFn - Optional callback for header metadata

deserializeGraphEdges(bytes): AsyncGenerator<Edge>

Streaming deserialize graph edges only.

Binary Format

FlatGeoGraphBuf uses FlatGeobuf's encoding for features and appends an optional graph section:

[FGG Magic: 8B] [Header: 4B+var] [Index?] [Features...] [Graph Section?]
  • FGG Magic: 0x6667670166676700 ("fgg\x01fgg\x00")
  • Header/Features: Same encoding as FlatGeobuf
  • Graph Section: [Header Size: 4B] [Graph Header] [Edges...]
  • Graph Header: Edge count + edge column schema
  • Edges: Size-prefixed records with [from: 4B][to: 4B][properties...]

Edge properties use the same encoding as FlatGeobuf feature properties, supporting:

  • Boolean, integers (8/16/32/64 bit signed/unsigned)
  • Float, Double
  • String, DateTime, JSON, Binary

See doc/format-spec.md for detailed specification.

Design Decisions

Directed Edges

Edges are always directed (from -> to). For bidirectional connections, create two edges.

No Self-Loops

Self-loops (from === to) are not allowed and will throw an error during serialization.

Vertex References

Edges reference vertices by their index in the GeoJSON FeatureCollection (0-based).

Backward Compatibility

New properties can be added to edges without breaking readers that don't expect them - they're simply ignored during parsing, just like FlatGeobuf feature properties.

Performance

FlatGeoGraphBuf inherits FlatGeobuf's performance characteristics:

  • Zero-copy deserialization where possible
  • Size-prefixed records for efficient streaming
  • No compression overhead (can be compressed externally)

The graph section is optimized for decode performance:

  • Fixed-size edge header (from/to indices)
  • Same property encoding as features (proven efficient)
  • Sequential edge reading

Use Cases

  • Road networks with intersection/segment topology
  • Utility networks (power, water, telecom)
  • Transportation graphs (routes, connections)
  • Any geospatial graph where features represent nodes and edges represent relationships

License

BSD-3-Clause

Credits

Based on FlatGeobuf by Bjorn Harrtell.