DOCS · GUIDE
Getting started
Install the package, add one bundler plugin, import GDAL like a module. This page gets you from zero to a converted file on every supported runtime.
BETA NOTE
v3 is in beta. The scoped prebuilt packages (
@gdal3.js/wasm, @gdal3.js/wasm-bundle) are being published stage by stage; the recipes below match the apps that ship inside the gdal3.js repository. The stable v2 line works today from npm and CDN; see the v2 tab.
Install
npm install gdal3.js@beta
npm install -D @cpp.js/plugin-vite # or -webpack / -rollup / -rspack / -metro
Then declare the native dependency once in cppjs.config.js at your project root:
import wasm from "@gdal3.js/wasm/cppjs.config.mjs";
export default {
dependencies: [wasm],
paths: { config: import.meta.url },
};
Browser (Vite)
import { defineConfig } from "vite";
import viteCppjsPlugin from "@cpp.js/plugin-vite";
export default defineConfig({
plugins: [viteCppjsPlugin()],
});
import "gdal3.js/Dataset.h";
import { initCppJs, Gdal } from "gdal3.js/Gdal.h";
const Module = await initCppJs({ useWorker: true, fs: { opfs: true } });
// put the user's file into OPFS; gdal sees it as /opfs/…
const dir = await navigator.storage.getDirectory();
const fh = await dir.getFileHandle(file.name, { create: true });
const ws = await fh.createWritable();
await ws.write(file); await ws.close();
const ds = await Gdal.open(`/opfs/${file.name}`);
const opts = await Module.toVector("VectorString", ["-f", "GPKG", "-t_srs", "EPSG:3857"]);
const out = await ds.vectorTranslate("/opfs/out.gpkg", opts);
await out.close();
The plugin compiles bridges, serves the wasm/data assets and sets the right headers in dev. The useWorker flag keeps GDAL off your UI thread; see workers.
Node.js
Same imports, no VFS hop: GDAL reads and writes the host filesystem directly. Bundle for Node with @cpp.js/plugin-rollup or -webpack, or use the prebuilt Node build from @gdal3.js/wasm-bundle.
import "gdal3.js/Dataset.h";
import { initCppJs, Gdal } from "gdal3.js/Gdal.h";
const Module = await initCppJs();
const ds = await Gdal.open("data/districts.gpkg");
const opts = await Module.toVector("VectorString", ["-f", "GeoJSON", "-t_srs", "EPSG:4326"]);
const out = await ds.vectorTranslate("out/districts.geojson", opts);
await out.close();
React Native (Expo & bare)
const { getDefaultConfig } = require("expo/metro-config");
const { mergeConfig } = require("metro-config");
const CppjsMetroPlugin = require("@cpp.js/plugin-metro");
const config = getDefaultConfig(__dirname);
module.exports = mergeConfig(config, { ...CppjsMetroPlugin(config) });
import "gdal3.js/Dataset.h";
import { initCppJs, Gdal } from "gdal3.js/Gdal.h";
const Module = await initCppJs(); // native GDAL over JSI, no wasm
const ds = await Gdal.open(pickedFileUri.replace("file://", ""));
const opts = await Module.toVector("VectorString", ["-f", "GPKG"]);
const out = await ds.vectorTranslate(outputPath, opts);
The native module builds during pod install (iOS) and the Gradle build (Android). New Architecture is supported; device files are opened by absolute path.
v2 · CDN (stable today)
<script src="https://cdn.jsdelivr.net/npm/gdal3.js@2.8.1/dist/package/gdal3.js"></script>
<script>
initGdalJs({ path: "https://cdn.jsdelivr.net/npm/gdal3.js@2.8.1/dist/package" })
.then(async (Gdal) => {
const file = document.querySelector("input[type=file]").files[0];
const input = await Gdal.open(file);
const out = await Gdal.ogr2ogr(input.datasets[0], ["-f", "GeoJSON"]);
const bytes = await Gdal.getFileBytes(out);
});
</script>
Where to next
- Virtual file system: where files live, how to read results back.
- Frameworks: Webpack, Rollup, Rspack, Vue, Svelte specifics.
- Examples: reprojection, mosaics, hillshades, zipped Shapefiles.
- Migration: coming from v2? The full mapping table.