smartcrop

A dependency-free JavaScript library that finds content-aware image crops using edge, skin-tone, and saturation analysis.

Library
npm
v2.0.5
12,953stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
45/100Fair
Development Activity0
Maintenance20
Community60
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
60/100Good
Architecture65
Code Quality60
Innovation55
Learning Curve60

smartcrop.js is a small, dependency-free JavaScript library that finds the best crop for an image using content-aware analysis rather than a simple center or fixed-aspect crop. It runs a sliding-window search over candidate crop rectangles and scores each one using a blend of edge detection, skin-tone detection, and saturation analysis, favoring crops that keep detailed, skin-toned, and saturated regions in frame while respecting rule-of-thirds composition.

The same core scoring engine works unmodified in the browser (via an HTML canvas backend) or in Node.js, since image decoding and resampling are abstracted behind a swappable imageOperations interface — companion packages like smartcrop-gm and smartcrop-sharp plug in ImageMagick or libvips backends for server-side use. An optional boost region API lets callers feed in externally detected regions (such as faces from a face-detection library) to bias the crop toward specific subjects.

What You Get

  • A single dependency-free smartcrop.crop() function that returns the best-scoring crop rectangle for any target width/height or aspect ratio.
  • A pluggable imageOperations/canvasFactory interface so the same scoring engine runs in the browser (canvas) or Node.js (via companion smartcrop-gm/smartcrop-sharp backends).
  • A boost region API for weighting externally detected regions (e.g. faces) so they’re prioritized when composing the crop.
  • Bundled TypeScript type definitions (index.d.ts) for typed crop()/CropOptions/CropResult usage.

Common Use Cases

  • Generating responsive thumbnail/hero images from user-uploaded photos without manual cropping.
  • Auto-cropping product or article images to a fixed aspect ratio for a CMS or gallery grid.
  • Building a face-aware avatar cropper by combining smartcrop’s boost API with a face-detection library like tracking.js.
  • Server-side batch image processing pipelines that need consistent, content-aware crops via smartcrop-sharp or smartcrop-gm.

Under The Hood

Architecture The library is implemented as a single self-executing IIFE (smartcrop.js) which exposes a smartcrop global with a pluggable image-operations abstraction (imageOperations/canvasFactory) so the same core scoring engine runs identically in the browser (canvas-backed open/resample/getData) or in Node when a caller supplies a replacement iop, as companion packages smartcrop-gm and smartcrop-sharp do. The core flow: crop() opens the image, optionally prescales it to a 256px-max dimension for performance, generates a grid of candidate crops via generateCrops() sliding a scale/step window over the image, runs three independent per-pixel detectors (edgeDetect, skinDetect, saturationDetect) that write into separate RGBA channels of a shared ImgData buffer, downsamples the combined buffer, then scores every candidate crop via an importance()-weighted sum (rule-of-thirds plus edge-distance falloff plus boost regions) and returns the top-scoring candidate. There is no class hierarchy or dependency injection beyond the swappable imageOperations — it’s one exported object closing over private helper functions that all operate on the same ImgData layout, so changing the core analyse()/score() pipeline would ripple through the whole scoring model.

Tech Stack Vanilla JavaScript with zero runtime dependencies — the only external requirement is a Promise implementation (native, or a user-supplied polyfill such as bluebird for older browsers). Dev tooling uses Grunt for a local dev server and file watching, Karma plus Mocha and Chai for browser test execution (configured for both local Chrome and Sauce Labs runners), ESLint (eslint:recommended plus custom indentation/quote/semicolon rules) for linting, and a hand-written TypeScript declaration file validated at test time via npx tsc -noEmit test/types.ts. It’s packaged for npm as a single-file main plus index.d.ts, still ships a legacy bower.json, and relies on separate companion repos (smartcrop-cli, smartcrop-gm, smartcrop-sharp) for CLI and server-side imaging rather than a monorepo. CI runs via GitHub Actions.

Code Quality Tests exist and run in-browser via Karma (against Chrome locally and multiple browsers via Sauce Labs in CI), covering isAvailable(), crop() output bounds, aspect ratio handling, and boost behavior. TypeScript types are checked with tsc -noEmit against a dedicated types.ts file as part of the test script. ESLint enforces consistent formatting on top of its recommended rule set. Error handling is minimal and implicit — the only explicit thrown error is for a missing Promise implementation — there’s no runtime validation of crop options, and the code favors ES5 patterns (var, a hand-rolled extend()) over modern strict-typed idioms. Naming is consistent, though pixel-processing loops use short single-letter variables typical of performance-sensitive image code.

What Makes It Unique Rather than a machine-learning model, smartcrop.js blends three classic heuristics — edge/detail detection, skin-tone matching, and saturation — into a single rule-of-thirds-weighted importance score, with an extensible boost-region API that lets callers inject externally detected regions (like faces from a separate face-detection library) at an arbitrary weight. Combined with its pluggable browser/Node backend design, this makes it a lightweight, dependency-free predecessor to the ML-based smart-crop features later built into CDNs and CMS platforms, trading algorithmic novelty for a small footprint and easy extensibility.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search