The Turf.js ecosystem provides a suite of modules for performing geospatial analysis in the browser and Node.js. @turf/turf acts as an all-in-one bundle containing every available function, ideal for quick prototyping or environments where bundle size is not a constraint. In contrast, @turf/helpers, @turf/invariant, and @turf/meta are granular, single-purpose modules designed for production applications where tree-shaking and minimal footprint are critical. @turf/helpers focuses on creating GeoJSON primitives, @turf/invariant provides robust type-checking and data extraction utilities, and @turf/meta offers high-performance iterators for traversing complex GeoJSON structures. Choosing between the monolithic bundle and the modular packages depends on whether you prioritize development speed or runtime performance.
When integrating geospatial logic into a modern web application, the choice between importing the entire Turf.js library versus selecting specific modules significantly impacts your application's load time and maintainability. The ecosystem offers @turf/turf, a comprehensive bundle, alongside specialized packages like @turf/helpers, @turf/invariant, and @turf/meta. Let's examine how these tools differ in practice and where each fits in a professional architecture.
@turf/turf is the "batteries-included" package. It exports every function available in the Turf.js ecosystem.
# Installs the entire library
npm install @turf/turf
// Usage: Access any function directly from the main export
import turf from '@turf/turf';
const point = turf.point([10, 20]);
const buffered = turf.buffer(point, 5, { units: 'kilometers' });
@turf/helpers, @turf/invariant, and @turf/meta are modular packages.
# Install only the specific utilities you need
npm install @turf/helpers @turf/invariant @turf/meta
// Usage: Import specific functions from their respective packages
import { point } from '@turf/helpers';
import { getCoord } from '@turf/invariant';
import { coordEach } from '@turf/meta';
const myPoint = point([10, 20]);
const coords = getCoord(myPoint);
Generating valid GeoJSON manually is error-prone. You must remember the correct nesting of coordinates and properties.
@turf/helpers simplifies this by providing factory functions.
// @turf/helpers: Creating a Point with properties
import { point } from '@turf/helpers';
const userLocation = point(
[-73.935242, 40.730610],
{ name: "Central Park", id: 123 },
{ id: "feature-1" }
);
// Result is a valid GeoJSON Feature object
@turf/turf includes these helpers but exposes them under the main namespace.
// @turf/turf: Same operation via the monolithic bundle
import turf from '@turf/turf';
const userLocation = turf.point(
[-73.935242, 40.730610],
{ name: "Central Park" }
);
@turf/invariant and @turf/meta do not create features.
@turf/helpers (or manual creation) requires you to construct raw JSON objects, increasing the risk of malformed data.Real-world data is often messy. A function might receive a Feature, a FeatureCollection, or a raw Geometry. You need tools to safely extract coordinates regardless of the input wrapper.
@turf/invariant provides robust type guards and extractors.
getCoord works on Points, Features, or even arrays, normalizing the output to a simple coordinate array.getType safely identifies the geometry type without throwing errors on malformed inputs.// @turf/invariant: Safe extraction
import { getCoord, getType } from '@turf/invariant';
// Works whether input is a Feature or raw Geometry
const input = { type: "Feature", geometry: { type: "Point", coordinates: [0, 0] } };
const coords = getCoord(input); // Returns [0, 0]
const type = getType(input); // Returns "Point"
@turf/turf exposes these as turf.getCoord and turf.getType.
// @turf/turf: Same extraction via bundle
import turf from '@turf/turf';
const coords = turf.getCoord(input);
@turf/helpers and @turf/meta do not provide validation logic.
GeoJSON objects can be deeply nested. A FeatureCollection might contain Features, which contain GeometryCollections, which contain multiple coordinate arrays. Writing recursive loops for this is tedious and slow.
@turf/meta offers high-performance iterators.
coordEach visits every coordinate pair in a geometry, no matter how deep the nesting.propEach iterates over features in a collection efficiently.// @turf/meta: Iterating every coordinate
import { coordEach } from '@turf/meta';
import { featureCollection, polygon } from '@turf/helpers';
const poly = polygon([[[0,0], [10,0], [10,10], [0,10], [0,0]]]);
const fc = featureCollection([poly]);
let count = 0;
coordEach(fc, (coord) => {
count++;
// Process each [lon, lat] pair
});
@turf/turf includes these iterators as turf.coordEach.
// @turf/turf: Iterator via bundle
import turf from '@turf/turf';
turf.coordEach(fc, (coord) => { /* ... */ });
@turf/helpers and @turf/invariant lack iteration capabilities.
@turf/turfUse the monolithic bundle for Node.js scripts, build-time tools, or rapid prototypes where developer convenience outweighs bundle size concerns. It is also acceptable for internal dashboards where network load is not a user-facing metric.
helpers, invariant, meta)Adopt the modular approach for production web applications, mobile web views, or SDKs distributed to third parties.
@turf/helpers to build your data structures.@turf/invariant to sanitize inputs from APIs or user uploads.@turf/meta when you need to write custom processing logic that the standard analysis modules don't cover.| Feature | @turf/turf | @turf/helpers | @turf/invariant | @turf/meta |
|---|---|---|---|---|
| Primary Goal | All-in-one convenience | Create GeoJSON | Validate & Extract | Traverse Data |
| Bundle Size | Large (Full Library) | Tiny | Tiny | Tiny |
| Tree-Shaking | Limited (unless ESM used carefully) | Excellent | Excellent | Excellent |
| Key Methods | buffer, distance, point | point, lineString, feature | getCoord, getType | coordEach, propEach |
| Best For | Prototypes, Server Scripts | Data Generation | Input Sanitization | Custom Algorithms |
For modern frontend development, avoid @turf/turf unless you have a specific reason to include the entire library. The modular packages (@turf/helpers, @turf/invariant, @turf/meta) provide the same robust functionality with a fraction of the weight. By composing these small, focused modules, you ensure your application remains fast while retaining the full power of geospatial analysis. Start with helpers to define your data, use invariant to protect your logic, and reach for meta when you need to dig deep into complex geometries.
Choose @turf/helpers when your primary need is to programmatically generate GeoJSON features, points, lines, or collections without pulling in heavy analysis algorithms. This is the foundational package for creating valid spatial data structures and should be included in almost any project that dynamically constructs maps or spatial inputs.
Choose @turf/invariant when you need to validate GeoJSON inputs, extract coordinates reliably, or determine the geometric type of a feature before running calculations. It is essential for writing robust functions that handle messy real-world data, ensuring your application doesn't crash when encountering unexpected geometry formats.
Choose @turf/meta when you need to iterate over complex GeoJSON objects (like FeatureCollections or GeometryCollections) efficiently. If you are building custom analysis logic that requires visiting every coordinate or feature without the overhead of loading full analysis modules, this package provides the necessary low-level traversal tools.
Choose @turf/turf when you are building a prototype, running a server-side script where bundle size is irrelevant, or need immediate access to the entire geospatial toolkit without managing multiple imports. It is the fastest way to get started but results in a large JavaScript bundle that includes unused code, making it unsuitable for performance-sensitive frontend applications.
Linear measurement units.
⚠️ Warning. Be aware of the implications of using radian or degree units to measure distance. The distance represented by a degree of longitude varies depending on latitude.
See https://www.thoughtco.com/degree-of-latitude-and-longitude-distance-4070616 for an illustration of this behaviour.
Type: ("meters" | "metres" | "m" | "millimeters" | "millimetres" | "mm" | "centimeters" | "centimetres" | "cm" | "kilometers" | "kilometres" | "km" | "miles" | "mi" | "nauticalmiles" | "nmi" | "inches" | "in" | "yards" | "yd" | "feet" | "ft" | "radians" | "rad" | "degrees" | "deg")
Area measurement units.
Type: (Exclude<Units, ("radians" | "rad" | "degrees" | "deg")> | "acres" | "ac" | "hectares" | "ha")
Grid types.
Type: ("point" | "square" | "hex" | "triangle")
Shorthand corner identifiers.
Type: ("sw" | "se" | "nw" | "ne" | "center" | "centroid")
Geometries made up of lines i.e. lines and polygons.
Type: (LineString | MultiLineString | Polygon | MultiPolygon)
Convenience type for all possible GeoJSON.
Type: (Feature | FeatureCollection | Geometry | GeometryCollection)
The Earth radius in meters. Used by Turf modules that model the Earth as a sphere. The mean radius was selected because it is recommended by the Haversine formula (used by turf/distance) to reduce error.
Type: number
Unit of measurement factors based on earthRadius.
Keys are the name of the unit, values are the number of that unit in a single radian
Area of measurement factors based on 1 square meter.
Type: Record<AreaUnits, number>
Wraps a GeoJSON Geometry in a GeoJSON Feature.
geom (G | null)
properties GeoJsonProperties an Object of key-value pairs to add as properties (optional, default {})
options Object Optional Parameters (optional, default {})
options.bbox BBox? Bounding Box Array [west, south, east, north] associated with the Featureoptions.id Id? Identifier associated with the Featuregeometry GeometryObject input geometry
var geometry = {
"type": "Point",
"coordinates": [110, 50]
};
var feature = turf.feature(geometry);
//=feature
Returns Feature<GeometryObject, GeoJsonProperties> a GeoJSON Feature
Creates a GeoJSON Geometry from a Geometry string type & coordinates.
For GeometryCollection type use helpers.geometryCollection
type ("Point" | "LineString" | "Polygon" | "MultiPoint" | "MultiLineString" | "MultiPolygon") Geometry Typecoordinates Array<any> Coordinates_options Record<string, never> (optional, default {})options Object Optional Parameters (optional, default {})var type = "Point";
var coordinates = [110, 50];
var geometry = turf.geometry(type, coordinates);
// => geometry
Returns Geometry a GeoJSON Geometry
Creates a Point Feature from a Position.
coordinates Position longitude, latitude position (each in decimal degrees)
properties GeoJsonProperties an Object of key-value pairs to add as properties (optional, default {})
options Object Optional Parameters (optional, default {})
options.bbox BBox? Bounding Box Array [west, south, east, north] associated with the Featureoptions.id Id? Identifier associated with the Featurevar point = turf.point([-75.343, 39.984]);
//=point
Returns Feature<Point, GeoJsonProperties> a Point feature
Creates a Point FeatureCollection from an Array of Point coordinates.
properties GeoJsonProperties Translate these properties to each Feature (optional, default {})
options Object Optional Parameters (optional, default {})
options.bbox BBox? Bounding Box Array [west, south, east, north]
associated with the FeatureCollectionoptions.id Id? Identifier associated with the FeatureCollectionvar points = turf.points([
[-75, 39],
[-80, 45],
[-78, 50]
]);
//=points
Returns FeatureCollection<Point> Point Feature
Creates a Polygon Feature from an Array of LinearRings.
properties GeoJsonProperties an Object of key-value pairs to add as properties (optional, default {})
options Object Optional Parameters (optional, default {})
options.bbox BBox? Bounding Box Array [west, south, east, north] associated with the Featureoptions.id Id? Identifier associated with the Featurevar polygon = turf.polygon([[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]], { name: 'poly1' });
//=polygon
Returns Feature<Polygon, GeoJsonProperties> Polygon Feature
Creates a Polygon FeatureCollection from an Array of Polygon coordinates.
properties GeoJsonProperties an Object of key-value pairs to add as properties (optional, default {})
options Object Optional Parameters (optional, default {})
options.bbox BBox? Bounding Box Array [west, south, east, north] associated with the Featureoptions.id Id? Identifier associated with the FeatureCollectionvar polygons = turf.polygons([
[[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]],
[[[-15, 42], [-14, 46], [-12, 41], [-17, 44], [-15, 42]]],
]);
//=polygons
Returns FeatureCollection<Polygon, GeoJsonProperties> Polygon FeatureCollection
Creates a LineString Feature from an Array of Positions.
properties GeoJsonProperties an Object of key-value pairs to add as properties (optional, default {})
options Object Optional Parameters (optional, default {})
options.bbox BBox? Bounding Box Array [west, south, east, north] associated with the Featureoptions.id Id? Identifier associated with the Featurevar linestring1 = turf.lineString([[-24, 63], [-23, 60], [-25, 65], [-20, 69]], {name: 'line 1'});
var linestring2 = turf.lineString([[-14, 43], [-13, 40], [-15, 45], [-10, 49]], {name: 'line 2'});
//=linestring1
//=linestring2
Returns Feature<LineString, GeoJsonProperties> LineString Feature
Creates a LineString FeatureCollection from an Array of LineString coordinates.
properties GeoJsonProperties an Object of key-value pairs to add as properties (optional, default {})
options Object Optional Parameters (optional, default {})
options.bbox BBox? Bounding Box Array [west, south, east, north]
associated with the FeatureCollectionoptions.id Id? Identifier associated with the FeatureCollectionvar linestrings = turf.lineStrings([
[[-24, 63], [-23, 60], [-25, 65], [-20, 69]],
[[-14, 43], [-13, 40], [-15, 45], [-10, 49]]
]);
//=linestrings
Returns FeatureCollection<LineString, GeoJsonProperties> LineString FeatureCollection
Takes one or more Features and creates a FeatureCollection.
features Array<Feature<GeometryObject, GeoJsonProperties>> input features
options Object Optional Parameters (optional, default {})
options.bbox BBox? Bounding Box Array [west, south, east, north] associated with the Featureoptions.id Id? Identifier associated with the Featurevar locationA = turf.point([-75.343, 39.984], {name: 'Location A'});
var locationB = turf.point([-75.833, 39.284], {name: 'Location B'});
var locationC = turf.point([-75.534, 39.123], {name: 'Location C'});
var collection = turf.featureCollection([
locationA,
locationB,
locationC
]);
//=collection
Returns FeatureCollection<GeometryObject, GeoJsonProperties> FeatureCollection of Features
Creates a Feature<MultiLineString> based on a coordinate array. Properties can be added optionally.
properties GeoJsonProperties an Object of key-value pairs to add as properties (optional, default {})
options Object Optional Parameters (optional, default {})
options.bbox BBox? Bounding Box Array [west, south, east, north] associated with the Featureoptions.id Id? Identifier associated with the Featurevar multiLine = turf.multiLineString([[[0,0],[10,10]]]);
//=multiLine
Returns Feature<MultiLineString, GeoJsonProperties> a MultiLineString feature
Creates a Feature<MultiPoint> based on a coordinate array. Properties can be added optionally.
properties GeoJsonProperties an Object of key-value pairs to add as properties (optional, default {})
options Object Optional Parameters (optional, default {})
options.bbox BBox? Bounding Box Array [west, south, east, north] associated with the Featureoptions.id Id? Identifier associated with the Featurevar multiPt = turf.multiPoint([[0,0],[10,10]]);
//=multiPt
Returns Feature<MultiPoint, GeoJsonProperties> a MultiPoint feature
Creates a Feature<MultiPolygon> based on a coordinate array. Properties can be added optionally.
properties GeoJsonProperties an Object of key-value pairs to add as properties (optional, default {})
options Object Optional Parameters (optional, default {})
options.bbox BBox? Bounding Box Array [west, south, east, north] associated with the Featureoptions.id Id? Identifier associated with the Featurevar multiPoly = turf.multiPolygon([[[[0,0],[0,10],[10,10],[10,0],[0,0]]]]);
//=multiPoly
Returns Feature<MultiPolygon, GeoJsonProperties> a multipolygon feature
Creates a Feature
geometries Array<(Point | LineString | Polygon | MultiPoint | MultiLineString | MultiPolygon)> an array of GeoJSON Geometries
properties GeoJsonProperties an Object of key-value pairs to add as properties (optional, default {})
options Object Optional Parameters (optional, default {})
options.bbox BBox? Bounding Box Array [west, south, east, north] associated with the Featureoptions.id Id? Identifier associated with the Featurevar pt = turf.geometry("Point", [100, 0]);
var line = turf.geometry("LineString", [[101, 0], [102, 1]]);
var collection = turf.geometryCollection([pt, line]);
// => collection
Returns Feature<GeometryCollection, GeoJsonProperties> a GeoJSON GeometryCollection Feature
Round number to precision
turf.round(120.4321)
//=120
turf.round(120.4321, 2)
//=120.43
Returns number rounded number
Convert a distance measurement (assuming a spherical Earth) from radians to a more friendly unit. Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet
radians number in radians across the sphereunits Units can be degrees, radians, miles, inches, yards, metres,
meters, kilometres, kilometers. (optional, default "kilometers")Returns number distance
Convert a distance measurement (assuming a spherical Earth) from a real-world unit into radians Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet
distance number in real unitsunits Units can be degrees, radians, miles, inches, yards, metres,
meters, kilometres, kilometers. (optional, default "kilometers")Returns number radians
Convert a distance measurement (assuming a spherical Earth) from a real-world unit into degrees Valid units: miles, nauticalmiles, inches, yards, meters, metres, centimeters, kilometres, feet
distance number in real unitsunits Units can be degrees, radians, miles, inches, yards, metres,
meters, kilometres, kilometers. (optional, default "kilometers")Returns number degrees
Converts any bearing angle from the north line direction (positive clockwise) and returns an angle between 0-360 degrees (positive clockwise), 0 being the north line
bearing number angle, between -180 and +180 degreesReturns number angle between 0 and 360 degrees
Converts any azimuth angle from the north line direction (positive clockwise) and returns an angle between -180 and +180 degrees (positive clockwise), 0 being the north line
angle number between 0 and 360 degreesReturns number bearing between -180 and +180 degrees
Converts an angle in radians to degrees
radians number angle in radiansReturns number degrees between 0 and 360 degrees
Converts an angle in degrees to radians
degrees number angle between 0 and 360 degreesReturns number angle in radians
Converts a length from one unit to another.
length number Length to be convertedoriginalUnit Units Input length unit (optional, default "kilometers")finalUnit Units Returned length unit (optional, default "kilometers")Returns number The converted length
Converts an area from one unit to another.
area number Area to be convertedoriginalUnit AreaUnits Input area unit (optional, default "meters")finalUnit AreaUnits Returned area unit (optional, default "kilometers")Returns number The converted length
isNumber
num any Number to validateturf.isNumber(123)
//=true
turf.isNumber('foo')
//=false
Returns boolean true/false
isObject
input any variable to validateturf.isObject({elevation: 10})
//=true
turf.isObject('foo')
//=false
Returns boolean true/false, including false for Arrays and Functions
Recursively removes bounding boxes from a GeoJSON object.
This function mutates the input GeoJSON object.
geojson GeoJSON GeoJSON object whose bounding boxes should be removedReturns void
This module is part of the Turfjs project, an open source module collection dedicated to geographic algorithms. It is maintained in the Turfjs/turf repository, where you can create PRs and issues.
Install this single module individually:
$ npm install @turf/helpers
Or install the all-encompassing @turf/turf module that includes all modules as functions:
$ npm install @turf/turf