AbsoluteJS

Image Optimization

On-demand image resizing and format conversion powered by Sharp. Images are automatically converted to WebP or AVIF, resized to the requested width, cached to disk, and served with proper cache headers. Each framework has its own <Image> component: see the framework-specific Components page for usage.

#How It Works

AbsoluteJS registers a /_absolute/image endpoint automatically when your server starts. When a browser requests an optimized image:

1
Content negotiation
checks the browser's Accept header to determine the best output format (AVIF, WebP, or JPEG)
2
Cache lookup
checks the disk cache for a previously optimized version with matching URL, width, quality, and format
3
Sharp optimization
if not cached, loads the source image, auto-rotates based on EXIF, resizes to the requested width (never upscales), and converts to the negotiated format
4
Cache write
stores the optimized image to disk with metadata (ETag, TTL, content type)
5
Response
serves the image with Cache-Control, ETag, and Vary: Accept headers

#Configuration

Add an images object to your absolute.config.ts. All fields are optional : the defaults work well for most apps.

TS
// absolute.config.ts : basic image optimization
import { defineConfig } from '@absolutejs/absolute';

export default defineConfig({
  reactDirectory: './src/frontend',
  images: {
    quality: 80,
    formats: ['image/webp', 'image/avif']
  }
});

#All Options

TS
// absolute.config.ts : full image optimization config
import { defineConfig } from '@absolutejs/absolute';

export default defineConfig({
  reactDirectory: './src/frontend',
  images: {
    // Widths used for responsive srcset when layout is "responsive"
    deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],

    // Widths used for fixed-size images
    imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],

    // Output formats : the server picks the best one the browser supports
    formats: ['image/webp', 'image/avif'],

    // Minimum cache TTL in seconds for optimized images
    minimumCacheTTL: 60,

    // Allow remote images from specific origins
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 'images.example.com',
        port: '',
        pathname: '/assets/**'
      }
    ],

    // Output quality (1-100)
    quality: 80,

    // Custom endpoint path (default: '/_absolute/image')
    path: '/_absolute/image',

    // Disable optimization entirely (serve originals)
    unoptimized: false
  }
});
deviceSizesbreakpoints for device-width responsive images. Default: [640, 750, 828, 1080, 1200, 1920, 2048, 3840]
imageSizesbreakpoints for fixed-width images. Default: [16, 32, 48, 64, 96, 128, 256, 384]
formatsoutput formats in preference order. Default: ["webp"]. Add "avif" for smaller files at slower encode speed.
minimumCacheTTLcache duration in seconds. Default: 60.
qualitydefault quality 1-100. Default: 75.
remotePatternsallowed remote image origins for security.
pathcustom endpoint path. Default: "/_absolute/image".
unoptimizedglobally disable optimization. Images served as-is.

#Optimization Endpoint

The endpoint accepts three query parameters:

urlrequiredthe source image path or a full remote URL
wrequiredtarget width in pixels. Must be one of the configured deviceSizes or imageSizes values.
qoptionalquality 1-100. Defaults to the configured quality.
BASH
# The image optimization endpoint accepts these query parameters:
# url  : path to the source image (required)
# w    : desired width in pixels (required)
# q    : quality 1-100 (optional, defaults to config value)

# Fetch a 640px-wide WebP version
curl -H "Accept: image/webp" \
  "http://localhost:3000/_absolute/image?url=/images/hero.jpg&w=640&q=80"

# Fetch an AVIF version
curl -H "Accept: image/avif" \
  "http://localhost:3000/_absolute/image?url=/images/hero.jpg&w=1200&q=75"

# The server reads the Accept header and returns the best
# supported format. If the browser doesn't support WebP or AVIF,
# the original format is returned at the requested size.

#Content Negotiation

The endpoint reads the browser's Accept header to pick the best format. If the browser supports AVIF and it's in your formats config, AVIF is served. Otherwise WebP. Otherwise the source format. The response includes Vary: Accept so CDNs cache each variant separately.

#Caching

Optimized images are cached to disk at {buildDir}/.cache/images/. Each entry is keyed by a SHA-256 hash of the URL, width, quality, and format. Cache files persist across server restarts.

ETageach cached image gets a unique ETag. Browsers send If-None-Match on subsequent requests and get 304 Not Modified.
TTLset via minimumCacheTTL (seconds). After expiry, the next request regenerates the image.
Cache-Controlresponses include public, max-age=<TTL>, must-revalidate.

#Remote Images

By default, only local images are allowed. To optimize remote images, configure remotePatterns with the allowed origins. This prevents the endpoint from being used as an open proxy.

TS
// absolute.config.ts : allowing remote images
import { defineConfig } from '@absolutejs/absolute';

export default defineConfig({
  reactDirectory: './src/frontend',
  images: {
    remotePatterns: [
      // Allow all images from a specific CDN
      {
        protocol: 'https',
        hostname: 'cdn.example.com'
      },

      // Allow images from any subdomain of example.com
      {
        protocol: 'https',
        hostname: '*.example.com',
        pathname: '/images/**'
      },

      // Allow a specific path on a specific host
      {
        protocol: 'https',
        hostname: 'storage.googleapis.com',
        pathname: '/my-bucket/**'
      }
    ]
  }
});
hostnamesupports wildcards: "*.example.com" matches cdn.example.com, etc.
pathnamesupports glob prefixes: "/photos/**" matches any path starting with /photos/.

#AVIF Support

AVIF delivers ~20-30% smaller files than WebP but encoding is ~50x slower. AbsoluteJS handles this with async pre-generation:

  • Add "avif" to your formats array before "webp"
  • First request: browser gets WebP immediately
  • Background: AVIF variant is generated and cached
  • Next request from an AVIF-capable browser: served from cache instantly

#Sharp

Sharp is an optional peer dependency that wraps libvips for fast native image processing. Install it with:

BASH
bun add sharp

If Sharp is not installed, the optimization endpoint serves images unoptimized (original format and size) with a one-time console warning. This lets you develop without Sharp and add it when you're ready for production optimization.

#Type Reference

TS
type ImageConfig = {
  deviceSizes?: number[];
  imageSizes?: number[];
  formats?: ImageFormat[];
  minimumCacheTTL?: number;
  remotePatterns?: RemotePattern[];
  quality?: number;
  path?: string;
  unoptimized?: boolean;
};

type ImageFormat = 'image/webp' | 'image/avif';

type RemotePattern = {
  protocol?: 'http' | 'https';
  hostname: string;
  port?: string;
  pathname?: string;
};