These five libraries handle geometric calculations in JavaScript, but they serve different purposes within the graphics and mapping ecosystem. clipper-lib and polygon-clipping focus on boolean operations like union and intersection. d3-polygon provides basic 2D math such as area and centroids for visualization. earcut specializes in high-performance triangulation for rendering. turf offers a comprehensive suite of geospatial analysis tools based on the GeoJSON standard. Choosing the right one depends on whether you need raw speed, geospatial compliance, or specific mathematical operations.
When building mapping tools, data visualizations, or graphics engines, you will inevitably need to process polygon data. The JavaScript ecosystem offers several options, but they solve different problems. clipper-lib, d3-polygon, earcut, polygon-clipping, and turf all handle geometry, but their input formats, core capabilities, and output structures vary significantly. Let's break down how they handle common engineering tasks.
How you feed data into these libraries dictates how much preprocessing you must do. Some expect raw numbers, while others demand strict GeoJSON structures.
clipper-lib requires integer coordinates for precision.
{ X, Y } objects.// clipper-lib: Scaled integer coordinates
const scale = 1000000;
const subject = [{ X: 100 * scale, Y: 100 * scale }, { X: 200 * scale, Y: 100 * scale }];
d3-polygon accepts simple arrays of numbers.
[x, y] tuples directly.// d3-polygon: Raw coordinate arrays
const polygon = [[100, 100], [200, 100], [150, 200]];
earcut expects a flat array of vertices.
// earcut: Flat vertex array
const vertices = [100, 100, 200, 100, 150, 200];
const holes = [];
const dimensions = 2;
polygon-clipping uses standard coordinate nests.
[x, y] pairs.// polygon-clipping: Nested coordinate arrays
const polygon = [[[100, 100], [200, 100], [150, 200]]];
turf requires full GeoJSON Features.
// turf: GeoJSON Feature
const polygon = {
type: "Feature",
geometry: {
type: "Polygon",
coordinates: [[[100, 100], [200, 100], [150, 200]]]
}
};
Each library shines in a specific area. Some focus on boolean logic, others on rendering prep or basic math.
clipper-lib excels at boolean clipping.
Clipper class for union, intersect, or difference.ClipType and PolyFillType.// clipper-lib: Boolean Union
const clipper = new ClipperLib.Clipper();
clipper.AddPath(subject, ClipperLib.PolyType.ptSubject, true);
clipper.AddPath(clip, ClipperLib.PolyType.ptClip, true);
const solution = new ClipperLib.Paths();
clipper.Execute(ClipperLib.ClipType.ctUnion, solution);
d3-polygon focuses on basic measurements.
// d3-polygon: Calculate Area
import { polygonArea } from "d3-polygon";
const area = polygonArea(polygon);
earcut is built for triangulation.
// earcut: Triangulate
import earcut from "earcut";
const triangles = earcut(vertices, holes, dimensions);
// Returns indices like [0, 1, 2, 0, 2, 3...]
polygon-clipping handles boolean logic in pure JS.
union or intersection are top-level.// polygon-clipping: Boolean Union
import pc from "polygon-clipping";
const result = await pc.union(subjectPolygon, clipPolygon);
turf provides geospatial boolean ops.
union, intersect, difference.// turf: Boolean Union
import { union } from "@turf/turf";
const result = union(poly1, poly2);
What you get back determines how much post-processing is needed before rendering or saving.
clipper-lib returns scaled paths.
{ X, Y } objects.// clipper-lib: Deserialize results
const realPath = solution.map(p => ({
x: p.X / scale,
y: p.Y / scale
}));
d3-polygon returns single numbers or booleans.
polygonContains returns true or false.// d3-polygon: Check containment
import { polygonContains } from "d3-polygon";
const isInside = polygonContains(polygon, [150, 150]);
earcut returns a flat index list.
// earcut: Use indices for rendering
const indices = new Uint16Array(triangles);
// Upload to WebGL index buffer
polygon-clipping returns coordinate nests.
// polygon-clipping: Result format
// result is [[[x, y], [x, y]...]]
const geoJSON = {
type: "Polygon",
coordinates: result
};
turf returns GeoJSON Features.
// turf: Result format
// result is a GeoJSON Feature
console.log(result.geometry.type); // "Polygon"
You are building a tool where users draw zones that merge together.
polygon-clipping or turfturf is better if you need map projections.// turf: Merging zones
const merged = turf.union(zone1, zone2);
You need to render thousands of polygons in WebGL.
earcut// earcut: Preparing for GPU
const indices = earcut(vertices);
You are showing chart areas and need to calculate centroids for labels.
d3-polygon// d3-polygon: Label placement
const center = d3.polygonCentroid(polygon);
You are building a laser cutter interface requiring exact boolean differences.
clipper-lib// clipper-lib: Precision difference
clipper.Execute(ClipperLib.ClipType.ctDifference, solution);
| Feature | clipper-lib | d3-polygon | earcut | polygon-clipping | turf |
|---|---|---|---|---|---|
| Boolean Ops | ✅ Yes | ❌ No | ❌ No | ✅ Yes | ✅ Yes |
| Triangulation | ❌ No | ❌ No | ✅ Yes | ❌ No | ❌ No |
| Input Format | Scaled Objects | [x, y] Arrays | Flat Vertices | [x, y] Nests | GeoJSON |
| Precision | High (Integers) | Standard (Float) | Standard (Float) | Standard (Float) | Standard (Float) |
| GeoJSON Ready | ❌ No | ❌ No | ❌ No | ⚠️ Close | ✅ Yes |
clipper-lib is the heavy-duty engine 🏗️ for when precision matters most. It requires more setup but handles complex boolean logic without floating-point errors.
d3-polygon is the lightweight utility 🔧 for visualization tasks. It solves basic math problems quickly without pulling in heavy dependencies.
earcut is the renderer's friend 🎨 for turning shapes into triangles. It is the standard for WebGL and map tiles.
polygon-clipping is the balanced choice ⚖️ for boolean ops in pure JavaScript. It avoids the scaling hassle of clipper-lib while staying focused.
turf is the geospatial standard 🌍 for anything involving maps. It brings a full suite of analysis tools but comes with a larger bundle size.
Final Thought: Do not try to force one library to do another's job. Use earcut for rendering, turf for maps, and clipper-lib for precision engineering. Mixing them often leads to unnecessary data conversion and performance loss.
Choose clipper-lib when you need robust boolean operations on raw polygon paths and require high precision through integer scaling. It is a proven port of a C++ library, making it ideal for CAD-like applications or complex clipping tasks where floating-point errors are unacceptable. However, it requires manual coordinate scaling and has a steeper learning curve than pure JavaScript alternatives.
Choose d3-polygon if you are already using the D3 ecosystem for data visualization and need lightweight helpers for area, centroid, or convex hull calculations. It works directly with simple coordinate arrays and integrates seamlessly with SVG rendering pipelines. Avoid it for complex boolean logic or geospatial tasks, as it lacks support for those operations.
Choose earcut when your primary goal is triangulating polygons for WebGL rendering or map vector tiles. It is extremely fast and designed specifically to convert polygon vertices into triangle indices. Do not use it for boolean operations or geometric measurements, as it does not support those features.
Choose polygon-clipping for boolean operations when you want a pure JavaScript solution without native dependencies or coordinate scaling. It accepts standard coordinate arrays and returns GeoJSON-like structures, making it easier to integrate than clipper-lib. Be aware that development activity is slower compared to larger ecosystems like Turf.
Choose turf when working with geospatial data that requires GeoJSON compliance and a wide range of analysis tools beyond just polygons. It handles projections, units, and complex spatial queries out of the box. It is heavier than specialized libraries, so avoid it for simple 2D canvas tasks where performance and bundle size are critical.
forked from Javascript Clipper
The Javascript Clipper library performs clipping and offsetting for both lines and polygons. All four boolean clipping operations are supported - intersection, union, difference and exclusive-or. Polygons can be of any shape including self-intersecting polygons.
Javascript Clipper is a port of Angus Johnson's Clipper library: https://sourceforge.net/projects/polyclipping/
LIVE DEMO: http://jsclipper.sourceforge.net/6.2.1.0/main_demo.html
Information and examples: http://jsclipper.sourceforge.net/6.2.1.0/
Donate Javascript Clipper Project: https://sourceforge.net/p/jsclipper/wiki/Donations/
Use cases:
Algorithms, Graphics