npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

rectangles

v0.1.0

Published

Axis-aligned rectangle intersection, containment, bounds, measurement, and conversion utilities

Readme

Rectangles.js

NPM Package MIT license

Rectangles.js is a small, dependency-free TypeScript library for working with axis-aligned rectangles. It exports tree-shakable functions and a compatible Rectangles object that operates on plain objects.

The npm package is rectangles. Use it for lightweight axis-aligned bounding-box calculations with plain objects. Use a polygon or oriented-box library when rotation, clipping polygons, or minimum separating axes are required.

The library provides tools to:

  • test whether two rectangles intersect
  • compute their intersection or union
  • calculate area, perimeter, dimensions, and center points
  • test containment and translate rectangles without mutation
  • convert between corner and XYWH representations

Every rectangle is defined by two cartesian points:

  • (x1, y1) — top-left corner
  • (x2, y2) — bottom-right corner

Use normalize(a) before intersection operations when coordinate order is not guaranteed. Measurement, containment, union, center, and XYWH conversion already support reversed coordinates.

Installation

Install via npm:

npm install rectangles

Usage

Node (CommonJS)

const Rectangles = require('rectangles');

const A = { x1: 20, y1: 20, x2: 100, y2: 100 };
const B = { x1: 80, y1: 80, x2: 300, y2: 300 };

if (Rectangles.intersect(A, B)) {
  console.log(Rectangles.intersection(A, B));
} else {
  console.log('no intersection');
}

ES Modules

import Rectangles, { area, type Rectangle } from 'rectangles';

const rectangle: Rectangle = Rectangles.fromXYWH(10, 10, 50, 40);
console.log(area(rectangle));

Normalize, test, and measure overlap

Normalize rectangles before intersect() or intersection() when coordinate order is unknown.

import Rectangles from 'rectangles';

const a = Rectangles.normalize(Rectangles.fromXYWH(10, 20, 30, 40));
const b = Rectangles.normalize(Rectangles.fromXYWH(25, 30, 30, 15));

if (Rectangles.intersect(a, b)) {
  const overlap = Rectangles.intersection(a, b);
  console.log(overlap);                  // { x1: 25, y1: 30, x2: 40, y2: 45 }
  console.log(Rectangles.area(overlap)); // 225
}

Move a rectangle without mutation

import Rectangles from 'rectangles';

const source = { x1: 10, y1: 20, x2: 40, y2: 60 };
const moved = Rectangles.translate(source, 5, -5);

console.log(moved);  // { x1: 15, y1: 15, x2: 45, y2: 55 }
console.log(source); // unchanged

All methods are synchronous. Object-returning methods create new plain objects and do not mutate their inputs. Coordinates must be finite numbers; runtime validation is intentionally left to the caller.

Browser (global)

<script src="node_modules/rectangles/dist/rectangles.min.js"></script>
<script>
  const A = { x1: 0, y1: 0, x2: 10, y2: 10 };
  console.log(Rectangles.center(A));
</script>

RequireJS

<script src="require.js"></script>
<script>
requirejs(['node_modules/rectangles/dist/rectangles.min.js'], function (Rectangles) {
  const r = { x1: 0, y1: 0, x2: 10, y2: 20 };
  console.log(Rectangles.normalize(r));
});
</script>

Browser ES module

import Rectangles from 'rectangles/browser';

const rectangle = Rectangles.fromXYWH(10, 20, 30, 40);
console.log(Rectangles.toXYWH(rectangle));

Functions

intersect(a, b)

Determines whether two normalized rectangles intersect.

Returns true if they overlap with non-zero area, false otherwise (touching only at an edge or corner is not considered intersection).

intersection(a, b)

Calculates the intersection rectangle of two rectangles.

  • Assumes that intersect(a, b) is true.
  • Returns a rectangle { x1, y1, x2, y2 }.

normalize(a)

Normalizes a rectangle to ensure x1 <= x2 and y1 <= y2.

Useful when you are not sure about coordinate ordering.

area(a)

Calculates the area of a rectangle.

height(a)

Calculates the height of a rectangle.

width(a)

Calculates the width of a rectangle.

perimeter(a)

Calculates the perimeter of a rectangle.

center(a)

Calculates the center point of a rectangle.

Returns an object: { x, y }.

insetBy(a, w)

Applies the library's legacy inset transformation: it adds w to x1 and y1, and subtracts 2 * w from x2 and y2.

This is not a symmetric inset. For a conventional inset by w on every side, construct { x1: a.x1 + w, y1: a.y1 + w, x2: a.x2 - w, y2: a.y2 - w } instead.

  • Returns a new rectangle: { x1, y1, x2, y2 }.

union(a, b)

Calculates the bounding rectangle that contains both a and b.

Returns { x1, y1, x2, y2 }.

contains(a, b)

Checks whether rectangle a fully contains rectangle b.

Returns true or false.

containsPoint(a, p)

Checks whether rectangle a contains the point p.

  • p has the form { x, y }.
  • The boundary counts as “inside”.

Returns true or false.

translate(a, dx, dy)

Translates a rectangle by dx and dy.

Returns a new rectangle { x1, y1, x2, y2 }.

clone(a)

Returns a new rectangle containing the four coordinate properties.

equals(a, b)

Compares two rectangles for exact coordinate equality.

Returns true or false.

fromXYWH(x, y, width, height)

Creates a rectangle from x, y, width, height.

  • (x, y) is the top-left coordinate.
  • width and height may be negative.

Returns { x1, y1, x2, y2 }.

toXYWH(a)

Converts a rectangle to { x, y, width, height } representation.

  • Ensures width >= 0 and height >= 0, regardless of original x1/x2, y1/y2 order.

Development

Node.js 20 or newer is required for development.

npm install
npm test

Build CommonJS, ESM, browser, and declaration outputs with:

npm run build

Copyright and Licensing

Copyright (c) 2025-2026, Robert Eisele Licensed under the MIT license.