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

snap-crop

v0.1.1

Published

React image cropping component with crop and fill modes

Readme

Snap Crop

npm version license

A React image cropping component with both Crop Mode and Fill Mode.

✨ Features

  • 🖼️ Crop Mode: Crop images by adjusting the crop frame with zoom and pan
  • Circular Crop: Support for circular cropping masks
  • 📐 Fill Mode: Position images within a fixed frame with customizable fill color
  • 📝 Aspect Ratios: Support for 16:9, 9:16, 1:1, 4:3, 3:4
  • 💾 Export: Export to JPEG, PNG, or WebP with quality control
  • 📱 Responsive: Works on desktop and mobile
  • Controlled & Uncontrolled: Supports both controlled and uncontrolled usage patterns
  • 🔧 Flexible API: Pass through all react-easy-crop props for full customization

📦 Installation

npm install snap-crop
yarn add snap-crop
pnpm add snap-crop

Peer Dependencies

This package requires the following peer dependencies:

npm install react react-dom react-easy-crop

Styling Dependency

This package uses TailwindCSS for styling. Make sure your project has TailwindCSS configured. If you haven't set up TailwindCSS yet:

npm install tailwindcss @tailwindcss/vite

Then configure TailwindCSS in your project according to the official documentation.

🚀 Quick Start

import { useRef } from "react";
import { SnapCrop, SnapCropRef } from "snap-crop";

function App() {
  const snapCropRef = useRef<SnapCropRef>(null);

  const handleExport = async () => {
    await snapCropRef.current?.export({
      format: "jpeg",
      quality: 0.9,
      filename: "cropped-image.jpg",
    });
  };

  return (
    <div style={{ width: "100%", height: "500px" }}>
      <SnapCrop
        ref={snapCropRef}
        image="/path/to/image.jpg"
        aspect="16:9"
        mode="crop"
        fillColor="#FFFFFF"
      />
      <button onClick={handleExport}>Export</button>
    </div>
  );
}

📖 Usage Examples

Basic Crop Mode

import { SnapCrop, SnapCropRef } from "snap-crop";

function CropExample() {
  const ref = useRef<SnapCropRef>(null);

  return (
    <div style={{ width: "600px", height: "400px" }}>
      <SnapCrop
        ref={ref}
        image="/photo.jpg"
        aspect="16:9"
        mode="crop"
        showGrid={true}
      />
    </div>
  );
}

Circular Crop

function CircularCropExample() {
  const ref = useRef<SnapCropRef>(null);

  return (
    <div style={{ width: "400px", height: "400px" }}>
      <SnapCrop
        ref={ref}
        image="/avatar.jpg"
        aspect="1:1"
        mode="crop"
        cropShape="round"
        showGrid={false}
      />
    </div>
  );
}

Fill Mode with Custom Color

function FillExample() {
  const ref = useRef<SnapCropRef>(null);

  return (
    <div style={{ width: "600px", height: "400px" }}>
      <SnapCrop
        ref={ref}
        image="/photo.jpg"
        aspect="9:16"
        mode="fill"
        fillColor="#000000"
      />
    </div>
  );
}

Controlled Zoom & Position

You can control the zoom level and crop position externally:

function ControlledExample() {
  const ref = useRef<SnapCropRef>(null);
  const [zoom, setZoom] = useState(1);
  const [crop, setCrop] = useState({ x: 0, y: 0 });

  return (
    <div>
      <input
        type="range"
        min={1}
        max={3}
        step={0.1}
        value={zoom}
        onChange={(e) => setZoom(Number(e.target.value))}
      />
      <span>{zoom.toFixed(1)}x</span>

      <div style={{ width: "600px", height: "400px" }}>
        <SnapCrop
          ref={ref}
          image="/photo.jpg"
          aspect="16:9"
          mode="crop"
          zoom={zoom}
          onZoomChange={setZoom}
          crop={crop}
          onCropPositionChange={setCrop}
        />
      </div>
    </div>
  );
}

Export as Blob

Use getBlob() to get the image as a Blob for uploading:

const handleUpload = async () => {
  const blob = await snapCropRef.current?.getBlob({
    format: "png",
    quality: 1,
  });

  if (blob) {
    const formData = new FormData();
    formData.append("file", blob, "image.png");
    await fetch("/api/upload", { method: "POST", body: formData });
  }
};

📋 API Reference

SnapCrop Props

| Prop | Type | Default | Description | | ----------- | ----------------------- | ------------ | ----------------------------------------------------------------------------------------------------------- | | image | string | required | Image source URL or base64 string | | aspect | AspectRatio \| number | '16:9' | Aspect ratio preset ('16:9' | '9:16' | '1:1' | '4:3' | '3:4') or custom number (e.g., 2.35) | | mode | CropMode | 'crop' | Operating mode: 'crop' | 'fill' | | fillColor | string | '#FFFFFF' | Fill color for fill mode (hex or 'transparent') | | className | string | '' | Custom CSS class (supports Tailwind classes) |

Crop Mode Control Props

| Prop | Type | Description | | ---------------------- | ------------------------------------------ | --------------------------------------------------- | | crop | Point | Controlled crop position { x: number, y: number } | | onCropPositionChange | (crop: Point) => void | Callback when crop position changes | | zoom | number | Controlled zoom level | | onZoomChange | (zoom: number) => void | Callback when zoom changes | | onCropChange | (croppedArea, croppedAreaPixels) => void | Callback when crop area changes |

Cropper Props (passed through from react-easy-crop)

| Prop | Type | Default | Description | | ----------- | ------------------------ | ----------- | -------------------------------- | | minZoom | number | 1 | Minimum zoom level | | maxZoom | number | 3 | Maximum zoom level | | zoomSpeed | number | 0.2 | Zoom speed multiplier | | showGrid | boolean | true | Show grid overlay | | cropShape | 'rect' | 'round' | 'rect' | Shape of the crop area | | objectFit | 'contain' | 'cover' | 'contain' | How the image fits the container |

SnapCrop Ref Methods

Access these methods via useRef:

const snapCropRef = useRef<SnapCropRef>(null);

export(options?)

Export the current crop/fill result as a downloaded file.

await snapCropRef.current?.export({
  format: "jpeg", // 'jpeg' | 'png' | 'webp'
  quality: 0.9, // 0-1 (for jpeg and webp only)
  filename: "image.jpg",
});

getBlob(options?)

Get the current crop/fill result as a Blob.

const blob = await snapCropRef.current?.getBlob({
  format: "png",
  quality: 1,
});

reset()

Reset crop/fill to default position and zoom.

snapCropRef.current?.reset();

🎨 Styling

This component uses TailwindCSS for styling. Ensure TailwindCSS is configured in your project.

The component uses the following CSS class names that you can target for customization:

| Class | Description | | ------------- | ------------------- | | .snap-crop | Main container | | .crop-mode | Crop mode container | | .fill-mode | Fill mode container | | .fill-frame | Fill mode frame | | .fill-image | Image in fill mode |

Custom Styling Example

You can use the className prop to add additional Tailwind classes:

<SnapCrop
  className="rounded-lg overflow-hidden shadow-lg"
  // ... other props
/>

Or target the class names in your custom CSS:

.snap-crop {
  border-radius: 8px;
  overflow: hidden;
}

.fill-mode .fill-frame {
  border-radius: 4px;
}

📤 Exported Utilities

The package also exports utility functions:

import {
  // Image processing
  getCroppedImg,
  getFilledImg,
  downloadBlob,
  createImage,
  getExtension,

  // File validation
  validateImageFile,
  fileToDataUrl,
  getImageDimensions,

  // Constants
  ASPECT_RATIOS,
  DEFAULT_SIZES,
  PRESET_COLORS,
  MIN_IMAGE_SIZE,
  MAX_IMAGE_SIZE,
  MAX_FILE_SIZE,
} from "snap-crop";

🛠️ Development

# Install dependencies
npm install

# Start dev server
npm run dev

# Build library
npm run build:lib

# Type check
npm run typecheck

# Lint
npm run lint

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the project
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

📄 License

MIT © Lupeiwen0