Installation
pnpm add @drgd/aura sharp
Server-side usage requires the peer dependency sharp
to be installed as shown above.
client
Usage
Use the useAura
hook to extract colors on the client.
It accepts a remote image URL or a local static path (e.g., from your public
folder).
"use client";import { useAura } from "@drgd/aura/client";export function Colors({ imageUrl }: { imageUrl: string }) {// e.g., "/assets/my-image.webp" or "https://picsum.photos/200"const { colors, isLoading, error } = useAura(imageUrl, {paletteSize: 4,onError: (err) => console.error(err.message),});if (isLoading) return <p>Loading...</p>;if (error) return <p>Error: {error.message}</p>;return (<ul>{colors.map((color) => (<li key={color.hex}>{color.hex} - {Math.round(color.weight * 100)}%</li>))}</ul>);}
Parameters
imageUrl?: string | null
- URL of the image or a local static path
- Uses default
fallbackColors
if not provided
options?: object
paletteSize?: number
- Number of colors to extract (default: 6, range: 1-12)fallbackColors?: AuraColor[]
- Custom fallback colors arrayonError?: (error: Error) => void
- Error callback function
Returns
colors: AuraColor[]
- Array of extracted (or fallback) colors, sorted by weightisLoading: boolean
- Boolean indicating extraction statuserror: Error | null
- Error object if failed,null
otherwise otherwise
Demo

server
Usage
Use the getAura
function inside an async Server Component. It accepts a remote image URL or a Buffer
.
To prevent blocking the initial page load while colors are extracted, wrap getAura
call in <Suspense>
.
We use sharp
under the hood to process the image. Check out the sharp ↗ documentation for more information.
Example with an image URL
import { Suspense } from "react";import { getAura } from "@drgd/aura/server";// Server Component that gets the colorsasync function Colors({ imageUrl }: { imageUrl: string }) {const colors = await getAura(imageUrl, {paletteSize: 8, // Optional: Specify number of colors (1-12, default: 6)// quality: 'high', // Optional: 'low' (200px), 'medium' (400px), 'high' (800px)// timeout: 5000, // Optional: Max processing time in ms (default: 10000)// validateUrl: false, // Optional: Disable internal URL checks (default: true)// fallbackColors: [{ hex: '#...', weight: 1 }], // Optional: Custom fallbacks});return (<ul>{colors.map((color) => (<li key={color.hex} style={{ backgroundColor: color.hex }}>{color.hex} - {Math.round(color.weight * 100)}%</li>))}</ul>);}// Parent Server Componentexport default async function Page() {const imageUrl = "https://picsum.photos/200";return (<div><h1>Image Colors</h1><Suspense fallback={<p>Loading colors...</p>}><Colors imageUrl={imageUrl} /></Suspense></div>);}
Example with a local image
import fs from "fs";import path from "path";import { Suspense } from "react";import { getAura } from "@drgd/aura/server";// Server Component that gets the colorsasync function LocalColors({ imageFileName }: { imageFileName: string }) {const imagePath = path.join(process.cwd(), "public", "assets", imageFileName);let colors;try {const imageBuffer = await fs.readFile(imagePath);colors = await getAura(imageBuffer, { paletteSize: 8 });} catch (error) {console.error("Failed to process image", error);colors = await getAura(Buffer.from(""), { paletteSize: 5 });}return (<ul>{colors.map((color) => (<li key={color.hex} style={{ backgroundColor: color.hex }}>{color.hex} - {Math.round(color.weight * 100)}%</li>))}</ul>);}// Parent Server Componentexport default async function Page() {return (<div><h1>Image Colors</h1><Suspense fallback={<p>Loading colors...</p>}><LocalColors imageFileName="/assets/1.webp" /></Suspense></div>);}
Parameters
imageUrlOrBuffer: string | Buffer
- The URL of the image or a
Buffer
containing image data
- The URL of the image or a
options?: object
paletteSize?: number
- Number of colors to extract (default: 6, range: 1-12)quality?: "low" | "medium" | "high"
- "low" (200px) | "medium" (400px) | "high" (800px)timeout?: number
- Maximum processing time in milliseconds (default: 10000)fallbackColors?: AuraColor[]
- Custom fallback colors arrayvalidateUrl?: boolean
- Enable URL validation (default: true)
Returns
Promise<AuraColor[]>
- Array of extracted (or fallback) colors, sorted by weight
Error handling & Fallbacks
Both implementations include built-in error handling with fallback colors:
- Invalid image URLs
- Network errors
- Timeout errors (10s default)
- Invalid image types
- CORS errors
// Custom fallback colorsconst fallbackColors = [{ hex: "#FF0000", weight: 0.4 }, // Red{ hex: "#00FF00", weight: 0.3 }, // Green{ hex: "#0000FF", weight: 0.3 } // Blue];// Server-side usageconst colors = await getAura(imageUrl, {paletteSize: 3,fallbackColors});// Client-side usageconst { colors } = useAura(imageUrl, {paletteSize: 3,fallbackColors,onError: (error) => console.error(error)});