TypeScript port of Angus Johnson's Clipper2 library for polygon clipping, offsetting, and triangulation
In 2026, the original repository at AngusJohnson/Clipper2 was archived and primary development moved to PolyClipping/Clipper2. This port tracks the new repository
npm install clipper2-tsimport { intersect, union, difference, xor, inflatePaths, FillRule, JoinType, EndType } from 'clipper2-ts';
// Define polygons as arrays of points
const subject = [[
{ x: 0, y: 0 },
{ x: 100, y: 0 },
{ x: 100, y: 100 },
{ x: 0, y: 100 }
]];
const clip = [[
{ x: 50, y: 50 },
{ x: 150, y: 50 },
{ x: 150, y: 150 },
{ x: 50, y: 150 }
]];
// Boolean operations
const intersection = intersect(subject, clip, FillRule.NonZero);
const unionResult = union(subject, clip, FillRule.NonZero);
const diff = difference(subject, clip, FillRule.NonZero);
const xorResult = xor(subject, clip, FillRule.NonZero);
// Polygon offsetting (inflate/deflate)
const offset = inflatePaths(subject, 10, JoinType.Round, EndType.Polygon);The package ships as ES modules only. Node.js 20.19+, 22.12+ and 23+ can
require() it directly, as can bundlers:
const { intersect, FillRule } = require('clipper2-ts');This also covers TypeScript CLI tools that compile imports to require().
Older Node.js versions must use import() from CommonJS instead.
Convert polygons into triangles using constrained Delaunay triangulation:
import { triangulate, triangulateD, TriangulateResult } from 'clipper2-ts';
const polygon = [[
{ x: 0, y: 0 },
{ x: 100, y: 0 },
{ x: 100, y: 100 },
{ x: 0, y: 100 }
]];
const { result, solution } = triangulate(polygon);
if (result === TriangulateResult.success) {
// solution contains triangles (each with 3 vertices)
console.log(`Created ${solution.length} triangles`);
}
// For floating-point coordinates:
const { result: resultD, solution: solutionD } = triangulateD(polygon, 2);Points can optionally carry a Z value (e.g., elevation, layer index, color). Z callbacks allow you to assign Z values to new vertices created at intersection points. See Clipper2 Z Docs for details
Try the interactive example showing all Clipper2 operations
To run locally:
npm install
npm run serve
# Then open http://localhost:3000/example/This port follows the structure and functionality of Clipper2's C# implementation, with method names adapted to JavaScript conventions. Where C# uses PascalCase for methods (AddPath, Execute), this port uses camelCase (addPath, execute). Class names remain unchanged
For detailed API documentation, see the upstream Clipper2 docs as well as the previous full docs from the archived repo
The port validates against Clipper2's reference test suite plus regression tests for reported issues:
npm test # Run all tests
npm test:coverage # Run with coverage reportThe test suite validates clipping, offsetting, triangulation, and Z-callbacks against Clipper2's reference implementation. Polygon test 16 (bow-tie) uses relaxed tolerances as this edge case also fails in the C# reference
Unlike C# Clipper2, which has full int64 support, this library uses JavaScript's Number rather than BigInt for performance, with BigInt used for some intermediate arithmetic where needed. Coordinates must stay within the safe integer range (2^53); the library throws on overflow
If you have a use case that requires the full 64-bit range, and Clipper2-WASM isn't an option, please open an issue and we can discuss!
This library uses BigInt internally. Some versions/configurations of terser have had issues when compressing BigInt literals (eg 0n). clipper2-ts avoids BigInt literal syntax in its source to improve compatibility
If you still hit terser issues in a consuming build, one workaround is terserOptions: { compress: { evaluate: false } }
Faster than JavaScript-based Clipper (Clipper1) ports, slower than Clipper2-WASM; choose based on your constraints
Boost Software License 1.0 (same as Clipper2)
Original Clipper2 library by Angus Johnson. TypeScript port maintained by Jeremy Tribby
Benchmark polygon data from Poly2Tri (BSD 3-clause). See LICENSE_THIRD_PARTY for details