Architecture
This document describes the overall architecture of Turf.js, including its monorepo structure, layered dependency system, modular design principles, build pipeline, and external library integration strategy. For detailed information about the three foundation modules, see Foundation Modules. For the functional categorization of modules, see Module Categories. For the complete dependency hierarchy, see Dependency Hierarchy.
Monorepo Organization
Turf.js is organized as a Lerna-managed monorepo with over 100 individual packages located in the packages/ directory. The repository uses PNPM workspaces for dependency management and maintains a unified version number across all packages.
Package Management Configuration
Monorepo Package Management Structure
The root package.json2 sets "private": true, indicating this is a workspace root that does not publish itself. The lerna.json3-4 file configures Lerna to use PNPM as the npm client and maintains version 7.2.0 across all packages. The @turf/turf aggregator package packages/turf/package.json1-211 declares workspace dependencies on all individual modules using the "workspace:*" protocol packages/turf/package.json95-209
Layered Dependency System
Turf.js implements a four-tier dependency architecture that prevents circular dependencies and ensures modularity. Each tier builds upon the previous one, with clear separation of concerns.
Dependency Tier Structure
Four-Tier Dependency Architecture
| Tier | Purpose | Example Packages | Characteristics |
|---|---|---|---|
| Tier 0 | External dependencies | @types/geojson, jsts, rbush | Third-party libraries providing specialized algorithms |
| Tier 1 | Foundation utilities | @turf/helpers, @turf/meta, @turf/invariant | Used by nearly all other packages, no Turf dependencies |
| Tier 2 | Primitive operations | @turf/distance, @turf/bearing, @turf/bbox | Basic geometric calculations, depend only on Tier 1 |
| Tier 3 | Composite operations | @turf/along, @turf/buffer, @turf/line-slice | Combine Tier 2 primitives, limited external dependencies |
| Tier 4 | Complex algorithms | @turf/union, @turf/concave, @turf/clusters-kmeans | Advanced operations requiring external libraries |
The @turf/line-slice package demonstrates Tier 3 composition. Its package.json68-73 shows dependencies on foundation modules (@turf/helpers, @turf/invariant) and a Tier 2 module (@turf/nearest-point-on-line), but avoids external computational geometry libraries.
Modular Design Principles
Each Turf.js package follows a consistent structure with single responsibility, independent build artifacts, and standardized export patterns.
Standard Package Structure
Package Build Artifacts
Every package defines dual exports in its package.json using the exports field packages/turf-line-slice/package.json32-44 The "type": "module" field packages/turf-line-slice/package.json28 declares ES Module as the default format. The main, module, and types fields packages/turf-line-slice/package.json29-31 provide backward compatibility with older tooling.
Build System Architecture
The build system uses tsup for TypeScript compilation and produces multiple distribution formats to support different JavaScript environments.
Multi-Target Compilation Pipeline
Build Pipeline and Distribution Formats
Individual packages use a standardized build command: tsup --config ../../tsup.config.ts packages/turf-line-slice/package.json51 The main @turf/turf package extends this with Rollup: tsup --config ../../tsup.config.ts && rollup -c rollup.config.js packages/turf/package.json70
The Rollup configuration packages/turf/rollup.config.js1-23 creates a UMD bundle with Babel transpilation for ES5 compatibility, Node.js polyfills for browser usage, and Terser minification. The output uses the format "umd" with name "turf" packages/turf/rollup.config.js14 making the library available as window.turf in browsers.
Package Export Configuration
The dual-format export configuration supports both ES Module and CommonJS consumers:
| Export Field | Purpose | Value (ESM) | Value (CJS) |
|---|---|---|---|
type | Declares package type | "module" | N/A |
main | CommonJS entry | N/A | "dist/cjs/index.cjs" |
module | ES Module entry | "dist/esm/index.js" | N/A |
types | TypeScript types | "dist/esm/index.d.ts" | N/A |
exports["."].import | ES Module consumers | { types, default } | N/A |
exports["."].require | CommonJS consumers | N/A | { types, default } |
The exports field packages/turf-line-slice/package.json32-44 provides explicit entry points for different module systems, with separate TypeScript declaration files (.d.ts for ESM, .d.cts for CJS).
External Library Integration
Turf.js strategically integrates specialized external libraries for computationally intensive operations, focusing its own code on GeoJSON interoperability and API design.
Key External Dependencies
| Library | Purpose | Used By | Rationale |
|---|---|---|---|
jsts | Computational geometry algorithms | @turf/buffer, @turf/union, @turf/intersect, @turf/difference | Implements Java Topology Suite algorithms for robust boolean operations and buffering |
polyclip-ts | Martinez-Rueda boolean operations | Polygon boolean operations | Alternative to JSTS for certain polygon operations |
rbush | R-tree spatial indexing | @turf/clusters-kmeans, @turf/clusters-dbscan, @turf/nearest-point | Efficient spatial queries for clustering and nearest-neighbor operations |
d3-geo | Map projections | @turf/projection, @turf/great-circle | Azimuthal equidistant and other cartographic projections |
concaveman | Concave hull algorithm | @turf/concave | Specialized fast concave hull implementation |
skmeans | K-means clustering | @turf/clusters-kmeans | Statistical clustering algorithm |
earcut | Polygon triangulation | @turf/tesselate | Fast triangulation for polygon decomposition |
sweepline-intersections | Bentley-Ottmann algorithm | @turf/line-intersect | Efficient line segment intersection detection |
This architectural decision allows Turf.js to leverage battle-tested algorithms while maintaining a clean, GeoJSON-focused API surface.
Development and Quality Infrastructure
The repository includes comprehensive tooling for maintaining code quality and consistency across all packages.
Pre-commit and CI Pipeline
Quality Assurance Pipeline
The root package.json18-29 configures lint-staged to run on commit, executing ESLint fixes, Prettier formatting, and README regeneration. The prepare script package.json15 runs Husky setup and builds all packages on install. The test script package.json16 runs linting, then builds and tests all packages via Lerna.
The .monorepolint.config.mjs configuration (referenced in package.json12 and package.json34-37) enforces consistency rules across all packages, such as standardized package.json fields, dependency version alignment, and script naming conventions.
Version Management
All packages in the monorepo share a unified version number managed by Lerna, currently at version 7.2.0 lerna.json4 This synchronized versioning simplifies dependency management and ensures the entire ecosystem stays compatible. The Lerna publish command lerna.json5-8 handles publishing all changed packages to the npm registry simultaneously, maintaining version consistency across the @turf/* namespace.