{"id":10939,"library":"geotiff","title":"geotiff.js - GeoTIFF Image Decoding","description":"geotiff.js is a robust JavaScript library designed for decoding GeoTIFF and TIFF images in both browser and Node.js environments. It enables developers to read and parse these file formats, extract raw raster data across various data types and compressions (including Packbits, LZW, Deflate, JPEG, LERC, Zstandard, and WebP), and access rich geospatial metadata like GeoKeys and TIFF tags. The current stable version is 3.0.5, with ongoing active development and regular patch releases, alongside beta versions (e.g., 3.1.0-beta.0) that introduce new features like multi-stripped and tiled writing support. Key differentiators include its pure JavaScript implementation, configurable worker pools for efficient decoding, and selective reading of file portions to optimize bandwidth, making it an essential tool for web-based GIS applications that require client-side processing of georeferenced imagery.","status":"active","version":"3.0.5","language":"javascript","source_language":"en","source_url":"https://github.com/geotiffjs/geotiff.js","tags":["javascript","TIFF","GeoTIFF","image","raster","typescript"],"install":[{"cmd":"npm install geotiff","lang":"bash","label":"npm"},{"cmd":"yarn add geotiff","lang":"bash","label":"yarn"},{"cmd":"pnpm add geotiff","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"This is the primary asynchronous factory function for loading GeoTIFFs from remote URLs. Since v3, geotiff.js has largely moved towards ECMAScript Modules (ESM), making CommonJS 'require' syntax unreliable or unsupported for certain imports in Node.js environments.","wrong":"const { fromUrl } = require('geotiff');","symbol":"fromUrl","correct":"import { fromUrl } from 'geotiff'"},{"note":"Use this factory function for loading GeoTIFF data from a local JavaScript ArrayBuffer. Like `fromUrl`, it's an asynchronous operation, and ESM `import` is the recommended pattern in modern usage (v3+).","wrong":"const geotiff = require('geotiff'); const tiff = await geotiff.fromArrayBuffer(...);","symbol":"fromArrayBuffer","correct":"import { fromArrayBuffer } from 'geotiff'"},{"note":"The `Pool` class is used to manage Web Workers for parallelizing decoding tasks, significantly improving performance for large or complex GeoTIFFs. It should be imported directly from the top-level package, not from internal source paths which are subject to change.","wrong":"import { Pool } from 'geotiff/src/Pool';","symbol":"Pool","correct":"import { Pool } from 'geotiff'"},{"note":"This is a TypeScript type for the image object returned by `tiff.getImage()`. It's primarily used for type hinting and static analysis in TypeScript projects to ensure correct usage of image properties and methods.","symbol":"GeoTIFFImage","correct":"import { GeoTIFFImage } from 'geotiff'"}],"quickstart":{"code":"import { fromUrl, GeoTIFFImage } from 'geotiff';\n\nasync function processGeoTIFF() {\n  try {\n    // Example URL for a small GeoTIFF file (e.g., a Cloud Optimized GeoTIFF).\n    // In a real application, ensure the URL is accessible and CORS-friendly.\n    const url = 'https://geotiffjs.github.io/geotiff.js/test/data/example.tif';\n\n    console.log(`Attempting to open GeoTIFF from URL: ${url}`);\n    const tiff = await fromUrl(url);\n\n    // Get the first image (most common case). GeoTIFFs can contain multiple images.\n    const image: GeoTIFFImage = await tiff.getImage();\n    console.log(`Opened image: Width = ${image.getWidth()}, Height = ${image.getHeight()}`);\n\n    // Read raster data for the first band. The 'readRasters' method returns an array of TypedArrays.\n    // 'interleave: false' returns separate arrays for each band.\n    const rasters = await image.readRasters({ interleave: false });\n    console.log(`Read raster data. Number of bands: ${rasters.length}`);\n    if (rasters.length > 0 && rasters[0].length > 0) {\n      console.log(`First pixel value (band 0): ${rasters[0][0]}`);\n    }\n\n    // Access image metadata, such as GeoKeys or other TIFF tags.\n    const geoKeys = image.getGeoKeys();\n    console.log('GeoKeys (if present):', geoKeys);\n\n    // Get the bounding box of the image in its projected coordinates.\n    const boundingBox = image.getBoundingBox();\n    console.log('Bounding Box [minX, minY, maxX, maxY]:', boundingBox);\n\n    console.log('Successfully processed GeoTIFF.');\n  } catch (error) {\n    console.error('Error processing GeoTIFF:', error);\n  }\n}\n\nprocessGeoTIFF();","lang":"typescript","description":"Demonstrates how to asynchronously load a GeoTIFF from a URL, access its primary image, read raster data from its bands, and retrieve geospatial metadata like GeoKeys and the bounding box."},"warnings":[{"fix":"Review the v2 to v3 migration guide for specific API changes related to tag access, `getTiePoints()`, `getGDALMetadata()`, and `fileDirectory` properties. Ensure tag access is asynchronous where necessary.","message":"Version 3.0.0 introduced a breaking change with \"deferred tag reading\" (feat!: Implement deferred tag reading (#484)). This alters how TIFF tags and certain metadata (e.g., GeoKeys) are accessed, potentially requiring asynchronous handling (`await`) or different access patterns where direct synchronous property access might have worked previously.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Migrate your import statements to use ES module `import` syntax (`import { Name } from 'geotiff'`). Ensure your Node.js project is configured to treat `.js` files as ESM (e.g., by setting `\"type\": \"module\"` in `package.json` or using `.mjs` file extensions).","message":"Starting with v3, `geotiff.js` embraces ES Modules (ESM). While the `package.json` may support CommonJS (CJS) for some paths, direct `require()` calls for `geotiff` exports can lead to `ERR_REQUIRE_ESM` errors in Node.js, especially if underlying dependencies are ESM-only. A similar issue was seen in v2.0.5 with the `quick-lru` dependency.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Ensure you are using the latest patch release within your major version (e.g., 3.0.5 or a stable 3.1.x) to benefit from fixes related to source blocking and slicing. Report any issues with specific GeoTIFF files or custom sources to the maintainers.","message":"The library has shown sensitivity to data source handling and slicing, leading to `TypeError: Cannot read properties of undefined (reading 'offset')` errors in `BlockedSource.readSliceData` in previous versions (fixed in v2.1.4-beta.1) and a need to \"Restore pre-3.0.4 behavior to create blocked sources\" in v3.1.0-beta.0. This indicates potential edge cases with custom data sources or specific GeoTIFF structures that might not be handled robustly across all versions.","severity":"gotcha","affected_versions":">=2.0.0"},{"fix":"Ensure your Node.js environment is `node>=16.x` and your `tsconfig.json` (if applicable) uses `\"moduleResolution\": \"node16\"` or `\"bundler\"` to align with the package's intended module resolution strategy.","message":"The fix \"Use node16 moduleResolution for strict imports\" in v3.0.5 implies that older Node.js versions or non-standard TypeScript/build configurations might encounter module resolution issues, leading to failures to find modules or types.","severity":"gotcha","affected_versions":">=3.0.0"},{"fix":"Be prepared to write custom logic for advanced geospatial transformations and querying using the raw raster data and GeoKey metadata provided by the library. Consider using helper libraries like `geotiff-geokeys-to-proj4` if re-projection is a common requirement.","message":"While `geotiff.js` provides comprehensive decoding, it does not offer a high-level API for advanced geospatial operations like coordinate re-projection or direct querying of raster cells by geographic coordinates (similar to GDAL). Users need to implement such functionalities using the extracted metadata.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Convert your Node.js project or the specific file to use ES Modules with `import` statements and ensure `\"type\": \"module\"` is set in your `package.json`, or use an explicit `.mjs` extension.","cause":"Attempting to `require()` geotiff.js or its dependencies in a CommonJS module in Node.js, while geotiff.js (or its sub-dependencies) is an ES Module.","error":"Error [ERR_REQUIRE_ESM]: require() of ES Module /path/to/code/node_modules/quick-lru/index.js from /path/to/code/node_modules/geotiff/dist-node/source/blockedsource.js not supported."},{"fix":"Update `geotiff.js` to the latest patch release (e.g., 3.0.5 or 3.1.0-beta.0+) which includes fixes for these types of issues. If the problem persists, ensure your data source is correctly implemented if it's custom, or share the problematic GeoTIFF file with the maintainers for debugging.","cause":"An error occurred in `BlockedSource.readSliceData` due to issues with how data blocks or slices are being read from the source, often triggered under specific conditions with the last block or slices equal to block size.","error":"TypeError: Cannot read properties of undefined (reading 'offset')"},{"fix":"Use the `getTags()` method and await its result, or consult the `GeoTIFFImage` API for the correct asynchronous access pattern for the specific tag you need.","cause":"Direct synchronous access to TIFF tags or metadata properties on the `GeoTIFFImage` object after the v3.0.0 breaking change to deferred tag reading.","error":"Property 'SomeTag' does not exist on type 'GeoTIFFImage'. Did you mean 'getTags'?"},{"fix":"Ensure you are using type imports (`import type { GeoTIFFImage }`) only for type declarations, and not attempting to instantiate them as values. Verify the function signatures for the methods you are calling and provide arguments of the correct type.","cause":"Incorrect usage of TypeScript types, often when attempting to pass an object where a primitive type (like a number or string) is expected, or misinterpreting a type import as a callable constructor.","error":"Argument of type 'GeoTIFFImage' is not assignable to parameter of type 'number'."}],"ecosystem":"npm"}