A fully-typed, tree-shakeable TypeScript client for the GraphHopper Directions API, generated from its OpenAPI spec.
npm install @bradford-tech/graphhopper-sdkAlso works with pnpm add, yarn add, or bun add. From jsr:
deno add jsr:@bradford-tech/graphhopper-sdkThe client is ESM-only and runs on Node 20+, Deno, Bun, and edge runtimes (it uses the platform fetch, with no runtime dependencies).
Set your API key once on the shared client, then call any operation. The base URL (https://graphhopper.com/api/1) is preconfigured.
import { setApiKey, getGeocode } from "@bradford-tech/graphhopper-sdk";
setApiKey(process.env.GRAPHHOPPER_API_KEY!);
const { data } = await getGeocode({ query: { q: "Berlin" } });
console.log(data?.hits?.[0]?.point);
// => { lat: 52.5170365, lng: 13.3888599 }Every operation returns { data, error, response } — data is the typed response body, error is the typed error body on a non-2xx status, and response is the raw Response. Pass { throwOnError: true } to throw instead.
GraphHopper authenticates with an API key passed as the key query parameter. There are three ways to supply it.
Zero-config: set GRAPHHOPPER_API_KEY in the environment and every request uses it automatically — no code required.
Explicit, shared client: set the key once for all operations.
import { setApiKey } from "@bradford-tech/graphhopper-sdk";
setApiKey("your-api-key"); // overrides GRAPHHOPPER_API_KEY
// also accepts a resolver for rotation / secret managers:
setApiKey(() => loadKeyFromVault());Isolated clients: for multi-tenant servers, concurrent requests with different keys, or test isolation, create independent clients and pass one per call.
import { createGraphHopper, getGeocode } from "@bradford-tech/graphhopper-sdk";
const gh = createGraphHopper({ apiKey: "your-api-key" });
const { data } = await getGeocode({ client: gh, query: { q: "Berlin" } });Precedence is explicit (setApiKey / createGraphHopper) over the GRAPHHOPPER_API_KEY environment variable. Sign up and create a key to get started. Responses include X-RateLimit-* headers describing your remaining credit balance; a 429 means the daily or per-minute limit is exhausted.
All 20 operations from the spec are generated as standalone, tree-shakeable functions — import only what you use.
| Area | Functions |
|---|---|
| Routing | postRoute, getRoute |
| Matrix | postMatrix, getMatrix, calculateMatrix, getMatrixSolution |
| Isochrone | getIsochrone |
| Geocoding | getGeocode |
| Map Matching | postGpx |
| Route Optimization | solveVrp, asyncVrp, getSolution |
| Clustering | solveClusteringProblem, asyncClusteringProblem, getClusterSolution |
| Custom Profiles | postProfile, getProfile, calculateProfile, getProfileSolution, deleteProfile |
Point arrays are [longitude, latitude], matching the GraphHopper convention.
Route between two points:
import { postRoute } from "@bradford-tech/graphhopper-sdk";
const { data } = await postRoute({
body: {
profile: "car",
points: [
[13.388, 52.517], // Berlin
[13.397, 52.529],
],
},
});
console.log(data?.paths?.[0]?.distance, data?.paths?.[0]?.time);
// => 2675.2 (meters), 327000 (milliseconds)Compute a travel-time matrix between origins and destinations:
import { postMatrix } from "@bradford-tech/graphhopper-sdk";
const { data } = await postMatrix({
body: {
profile: "car",
from_points: [[13.388, 52.517]],
to_points: [
[13.397, 52.529],
[13.428, 52.523],
],
out_arrays: ["times"],
},
});
console.log(data?.times);
// => [[327, 681]] (seconds, one row per origin)GraphHopper publishes @graphhopper/directions-api-js-client. The two take different approaches:
@bradford-tech/graphhopper-sdk |
@graphhopper/directions-api-js-client |
|
|---|---|---|
| Source | Generated from the OpenAPI spec | Hand-written JS classes |
| Types | Full TypeScript types for every request and response | None (no .d.ts) |
| Module format | ESM, tree-shakeable per operation | Webpack UMD bundle, single import |
| Endpoint coverage | All 8 API areas (20 operations) | 6 areas — no Clustering or Custom Profiles |
| Runtime deps | None (platform fetch) |
Bundled |
| Convenience helpers | None | Polyline decoding, turn-sign labels, default params |
If you want typed responses, modern bundling, and the newer endpoints, use this SDK. If you rely on the official client's built-in helpers (such as polyline decoding), it still serves that case well.
git clone https://github.com/bradford-tech/graphhopper-sdk.git
cd graphhopper-sdk
npm install
npm run buildnpm run generate # regenerate the client from spec/openapi.json
npm run type-check # tsc --noEmit
npm run lint # eslint (zero warnings tolerance)
npm run fix # prettier + eslint auto-fix, then type-checkThe client in src/client is generated by @hey-api/openapi-ts from spec/openapi.json. A daily GitHub Actions workflow pulls the latest GraphHopper spec, regenerates the client, and opens a PR if anything changed.
Bug reports and pull requests are welcome on GitHub.