DOCS · GETTING STARTED · INTRODUCTION

Introduction

gdal3.js puts GDAL, the engine behind most of the GIS world, wherever JavaScript runs: WebAssembly in the browser and Node, and a real native library on iOS and Android. Same API everywhere, no server, no native install.

What it is

gdal3.js compiles GDAL, the real upstream C++, and exposes it to JavaScript:

You get the GDAL library itself, not its command-line apps: its operations exposed as API calls (translate, vectorTranslate/ogr2ogr, warp, rasterize, buildVRT, demProcessing, grid, nearblack, footprint, info…), the class API (Dataset, Driver, GCP), and ~80 utility statics on Gdal. This build ships 189 format drivers, the set its bundled dependencies enable; GDAL itself supports more, depending on which libraries are compiled in. v3 is a ground-up rewrite on cpp.js; the architecture guide goes under the hood.

That split is deliberate: with v3, compiling and packaging GDAL and the C++ libraries its drivers need is left to cpp.js, which ships them prebuilt through its package registry (an upstream upgrade is a single dependency bump). gdal3.js then concentrates on the parts that face you: easy, ergonomic usage, optimization (leaner, tunable builds) and documentation. Both are maintained by the same author (Buğra Sarı), so the cpp.js layer evolves in lockstep with gdal3.js rather than drifting as a third-party dependency.

Two ways to use it

GDAL is available from both sides of the bridge, and we recommend the C++ path when you need the complete GDAL API or maximum performance: in C++ you reach every GDAL class, mix gdal3.js's wrapper with GDAL's own headers, and batch a whole pipeline without crossing the JS↔wasm boundary on each call. The JavaScript binding exposes a curated wrapper over the same classes.

From C++, write the operation against the wrapper (a class under src/native) and pull in GDAL's own headers where you want the raw API; cpp.js exposes it all to JavaScript:

src/native/gis.h
#pragma once
#include <string>
#include <gdal.h>              // GDAL's own header
#include <gdal3js/Gdal.h>      // gdal3.js's high-level wrapper
#include <gdal3js/Dataset.h>

class Gis {
public:
  static int driverCount() { return GDALGetDriverCount(); }
  static std::string convert(std::string in, std::string out) {
    auto ds = Gdal::open(in);
    ds->vectorTranslate(out, {"-f", "GPKG"})->close();
    return out;
  }
};
main.js
import { initCppJs, Gis } from "./native/gis.h";

await initCppJs();
await Gis.driverCount();                    // e.g. 189
await Gis.convert(inputPath, "out.gpkg");

From JavaScript, import the wrapper, and GDAL's own headers too when you want a raw call, and use them directly:

main.js
import { initCppJs, Gdal } from "gdal3.js/Gdal.h";                 // wrapper
import { GDALGetDriverCount } from "@cpp.js/package-gdal/gdal.h";  // GDAL's own header

const Module = await initCppJs();
await GDALGetDriverCount();                                // e.g. 189, straight from GDAL
const ds   = await Gdal.openEx(inputPath);
const opts = await Module.toVector("VectorString", ["-f", "GPKG"]);
await ds.vectorTranslate("out.gpkg", opts);

Either way, gdal3.js ships a high-level C++ wrapper for GDAL, modern-C++ classes (Gdal, Dataset, Driver, GCP) over GDAL's C/C++ API, so you rarely reach for the raw C calls by hand, and the same classes are exposed to JS. The quick start has the full file layout, and the architecture guide goes under the hood.

Next steps