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

@snapkit-studio/react

v1.7.3

Published

React components for Snapkit image optimization

Downloads

23

Readme

@snapkit-studio/react

npm version npm downloads License: MIT TypeScript

React components and hooks for Snapkit Studio image optimization. This package provides high-performance React image components with automatic format optimization, responsive loading, and Next.js-compatible APIs.

Installation

npm install @snapkit-studio/react
# or
yarn add @snapkit-studio/react
# or
pnpm add @snapkit-studio/react

Features

  • React Image Component - Drop-in replacement for HTML img with optimization
  • Flexible CDN Configuration - Use Snapkit CDN or integrate with your existing infrastructure (CloudFront, GCS, Cloudflare)
  • Provider-less Architecture - Direct component usage without wrappers
  • Next.js Compatible - Same API as Next.js Image component
  • Environment Auto-Detection - Automatically reads framework-specific environment variables
  • Automatic Format Detection - AVIF, WebP, JPEG fallback
  • Responsive Images - Automatic srcset generation
  • DPR-based Optimization - Crisp images on high-DPI displays
  • Lazy Loading - Intersection Observer based
  • Network-aware Quality - Automatic adjustment based on connection
  • TypeScript Support - Full type definitions included

Quick Start

1. CDN Configuration

Choose between Snapkit CDN for zero-config optimization or custom CDN integration:

Option A: Snapkit CDN (Recommended)

# .env (Vite/CRA) - Snapkit CDN
VITE_IMAGE_CDN_PROVIDER=snapkit
VITE_SNAPKIT_ORGANIZATION=your-organization-name

Option B: Custom CDN Integration

# .env (Vite/CRA) - Custom CDN (Google Cloud Storage example)
VITE_IMAGE_CDN_PROVIDER=custom
VITE_IMAGE_CDN_URL=https://storage.googleapis.com/my-image-bucket

# AWS CloudFront example
# VITE_IMAGE_CDN_PROVIDER=custom
# VITE_IMAGE_CDN_URL=https://d1234567890.cloudfront.net

# Cloudflare or any custom domain
# VITE_IMAGE_CDN_PROVIDER=custom
# VITE_IMAGE_CDN_URL=https://images.example.com

2. Basic Usage

import { Image } from '@snapkit-studio/react';

function MyComponent() {
  return (
    <Image
      src="/project/hero.jpg"
      alt="Hero Image"
      width={800}
      height={600}
      priority
      transforms={{ format: 'auto' }}
    />
  );
}

Import Options

Selective Imports (Recommended)

// Image component only (~9 KB)

// Specific hooks only (~8 KB)
import { useImageOptimization } from '@snapkit-studio/react/hooks';
import { Image } from '@snapkit-studio/react/image';
// Utility functions only (~5 KB)
import {
  createImageStyle,
  mergeConfiguration,
} from '@snapkit-studio/react/utils';

Full Bundle Import

// Full bundle (~22 KB)
import { Image, useImageRefresh } from '@snapkit-studio/react';

CDN Configuration

The library supports flexible CDN configuration through environment variables. Configuration is automatically detected using getCdnConfig() from @snapkit-studio/core.

Snapkit CDN

Zero-configuration setup with automatic optimization, smart format delivery, and global edge caching:

# .env (Vite/CRA)
VITE_IMAGE_CDN_PROVIDER=snapkit
VITE_SNAPKIT_ORGANIZATION=your-organization-name

# .env.local (Next.js) - If using React package in Next.js
NEXT_PUBLIC_IMAGE_CDN_PROVIDER=snapkit
NEXT_PUBLIC_SNAPKIT_ORGANIZATION=your-organization-name

Custom CDN Integration

Use your existing CDN infrastructure with Snapkit's optimization features:

# .env (Vite/CRA) - Custom CDN examples
VITE_IMAGE_CDN_PROVIDER=custom
VITE_IMAGE_CDN_URL=https://your-cdn-domain.com

# .env.local (Next.js) - Custom CDN examples
NEXT_PUBLIC_IMAGE_CDN_PROVIDER=custom
NEXT_PUBLIC_IMAGE_CDN_URL=https://your-cdn-domain.com

Environment Variables Reference

Vite/CRA

| Variable | Required For | Description | | --------------------------- | ------------ | ----------------------------------- | | VITE_IMAGE_CDN_PROVIDER | All setups | CDN provider: snapkit or custom | | VITE_SNAPKIT_ORGANIZATION | Snapkit CDN | Your Snapkit organization name | | VITE_IMAGE_CDN_URL | Custom CDN | Your custom CDN base URL |

Next.js (when using React package)

| Variable | Required For | Description | | --------------------------------------- | ------------ | ----------------------------------- | | NEXT_PUBLIC_IMAGE_CDN_PROVIDER | All setups | CDN provider: snapkit or custom | | NEXT_PUBLIC_SNAPKIT_ORGANIZATION | Snapkit CDN | Your Snapkit organization name | | NEXT_PUBLIC_IMAGE_CDN_URL | Custom CDN | Your custom CDN base URL |

Image Component Props

| Prop | Type | Default | Description | | ------------------ | ------------------------------------- | -------- | ---------------------------- | | src | string | - | Image path (required) | | alt | string | - | Alt text (required) | | width | number | - | Image width | | height | number | - | Image height | | fill | boolean | false | Fill parent container | | sizes | string | - | Responsive size settings | | quality | number | 85 | Image quality (1-100) | | priority | boolean | false | Priority loading | | loading | 'lazy' \| 'eager' | 'lazy' | Loading method | | optimizeFormat | 'auto' \| 'avif' \| 'webp' \| 'off' | 'auto' | Format optimization | | transforms | ImageTransforms | {} | Image transformation options |

Key Features

Automatic Format Detection

The library uses Canvas-based detection to determine browser support for modern image formats:

// Automatically serves AVIF, WebP, or JPEG based on browser
<Image
  src="/photo.jpg"
  alt="Photo"
  width={800}
  height={600}
  optimizeFormat="auto"
/>

// Force specific format
<Image
  src="/logo.png"
  alt="Logo"
  width={200}
  height={100}
  optimizeFormat="webp"
/>

Format Selection Logic:

  1. AVIF: Chosen if browser supports it (Chrome 85+, Firefox 93+, Edge 91+, Safari 16+)
  2. WebP: Chosen if AVIF not supported but WebP is (Chrome 23+, Firefox 65+, Edge 79+, Safari 14+)
  3. JPEG: Final fallback for all other browsers

Detection Method:

  • Client-side: Uses Canvas.toDataURL() to test format support
  • Server-side: Conservative fallback to basic formats for SSR consistency

Responsive Images

// DPR-based srcset (1x, 2x, 3x) - default behavior
<Image
  src="/image.jpg"
  alt="High-DPI optimized"
  width={800}
  height={600}
/>

// Width-based srcset for responsive layouts
<Image
  src="/banner.jpg"
  alt="Responsive banner"
  width={1200}
  height={400}
  sizes="(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 25vw"
/>

Image Transformations

// Basic transformations
<Image
  src="/photo.jpg"
  alt="Transformed"
  width={400}
  height={400}
  transforms={{
    fit: "cover",      // contain | cover | fill | inside | outside
    quality: 90,       // Override quality
    blur: 20,          // Blur effect
    grayscale: true,   // Convert to grayscale
  }}
/>

// Extract/crop region
<Image
  src="/large-image.jpg"
  alt="Cropped section"
  width={300}
  height={200}
  transforms={{
    extract: {
      x: 100,
      y: 100,
      width: 300,
      height: 200,
    },
  }}
/>

Loading Control

// Priority loading for above-the-fold images
<Image
  src="/hero.jpg"
  alt="Hero image"
  width={1200}
  height={600}
  priority={true}
/>

// Lazy loading (default)
<Image
  src="/content.jpg"
  alt="Content image"
  width={400}
  height={300}
  loading="lazy"
/>

Event Handling

function ImageWithEvents() {
  const [isLoading, setIsLoading] = useState(true);
  const [hasError, setHasError] = useState(false);

  return (
    <div>
      {isLoading && <div>Loading...</div>}
      {hasError && <div>Failed to load image</div>}

      <Image
        src="/photo.jpg"
        alt="Photo"
        width={600}
        height={400}
        onLoad={() => {
          setIsLoading(false);
          console.log('Image loaded successfully');
        }}
        onError={() => {
          setIsLoading(false);
          setHasError(true);
          console.log('Failed to load image');
        }}
      />
    </div>
  );
}

Type Definitions

// Image component props
interface SnapkitImageProps {
  src: string;
  alt: string;
  width?: number;
  height?: number;
  fill?: boolean;
  sizes?: string;
  quality?: number;
  priority?: boolean;
  loading?: 'lazy' | 'eager';
  optimizeFormat?: 'auto' | 'avif' | 'webp' | 'off';
  transforms?: ImageTransforms;
  organizationName?: string;
  className?: string;
  style?: React.CSSProperties;
  onLoad?: React.ReactEventHandler<HTMLImageElement>;
  onError?: React.ReactEventHandler<HTMLImageElement>;
}

// Image transformations
interface ImageTransforms {
  width?: number;
  height?: number;
  quality?: number;
  format?: ImageFormat;
  fit?: 'contain' | 'cover' | 'fill' | 'inside' | 'outside';
  blur?: number;
  grayscale?: boolean;
  flip?: boolean;
  flop?: boolean;
  extract?: {
    x: number;
    y: number;
    width: number;
    height: number;
  };
}

// Image formats
type ImageFormat = 'auto' | 'avif' | 'webp' | 'jpeg' | 'png' | 'gif';

Migration from Next.js Image

The Snapkit Image component is designed to be a drop-in replacement for Next.js Image:

// Before (Next.js Image)
import Image from 'next/image';

<Image
  src="/photo.jpg"
  alt="Photo"
  width={800}
  height={600}
  quality={90}
  priority
  sizes="(max-width: 768px) 100vw, 50vw"
/>

// After (Snapkit Image)
import { Image } from '@snapkit-studio/react';

<Image
  src="/photo.jpg"
  alt="Photo"
  width={800}
  height={600}
  quality={90}
  priority
  sizes="(max-width: 768px) 100vw, 50vw"
  // Additional Snapkit features
  transforms={{ fit: "cover" }}
  optimizeFormat="auto"
/>

Live Demo

Experience all features in action with our interactive demo:

🚀 Live Demo → - Real-time examples with source code

Explore features including:

  • Image transformations with live preview
  • Error boundary demonstrations
  • Network-aware quality adjustments
  • DPR optimization examples
  • All component props and configurations

Browser Support

  • AVIF: Chrome 85+, Firefox 93+, Edge 91+ (Chromium), Safari 16+
  • WebP: Chrome 23+, Firefox 65+, Edge 79+ (Chromium), Safari 14+
  • Lazy Loading: Chrome 76+, Firefox 75+, Edge 79+, Safari 15.4+
  • Intersection Observer: Chrome 58+, Firefox 55+, Edge 79+, Safari 12.1+

Note: Only Chromium-based Edge (79+) is supported. Legacy EdgeHTML Edge (18 and below) is not supported.

Format Selection: Automatically selects the best supported format in order: AVIF → WebP → JPEG. Falls back to JPEG in browsers that don't support modern formats.

Testing

The package includes comprehensive test coverage with automatic coverage reporting:

# Run tests
npm test

# Run with coverage report
npm run test:coverage

# Watch mode for development
npm test -- --watch

Test Coverage

The package maintains high test coverage standards:

  • Coverage Threshold: 80% minimum for branches, functions, lines, and statements
  • Test Framework: Vitest with jsdom environment and v8 coverage provider
  • Coverage Reports: Text (console), JSON, HTML, and LCOV formats
  • Coverage Exclusions: Test files, configuration files, type definitions, and test utilities

Coverage reports are generated in multiple formats:

  • Text: Console output during test runs
  • HTML: Detailed coverage report in coverage/ directory
  • LCOV: For CI/CD integration and coverage tools
  • JSON: Machine-readable coverage data

Test Environment

Tests run in a jsdom environment to simulate browser behavior for React components testing.

Development

# Install dependencies
npm install

# Build package
npm run build

# Watch mode for development
npm run dev

# Type checking
npm run check-types

# Linting
npm run lint

Contributing

See the main repository README for contribution guidelines.

License

MIT