@immagin/client
v1.0.3
Published
Node.js and browser client for the Immagin image processing API
Maintainers
Readme
@immagin/client
Node.js and browser client for the Immagin image processing API.
Zero dependencies. Works everywhere fetch is available.
Install
npm install @immagin/clientQuick start
import { Immagin } from '@immagin/client'
const client = new Immagin({ apiKey: 'imk_...' })
// Generate a signed image URL (auto-fetches tenant credentials)
const url = await client.images.url('photos/hero.jpg', [
{ resize: { width: 800, height: 600 } },
])
// Upload an image (auto-detects MIME type)
import { readFileSync } from 'node:fs'
const buffer = readFileSync('photo.jpg')
await client.images.upload(buffer, 'photos/hero.jpg')Images
Generate image URLs
Generate signed image URLs for serving processed images. All URLs are automatically signed — the signature locks transformation parameters so they can't be tampered with.
// Original image
const url = await client.images.url('photo.jpg')
// With transformations
const thumb = await client.images.url('photo.jpg', [
{ resize: { width: 800, height: 600 } },
{ text: { text: '© My Company', position: 'bottom-right', opacity: 0.5 } },
])
// Rotate, blur, grayscale
const edited = await client.images.url('photo.jpg', [
{ rotate: { angle: 90 } },
{ blur: 3 },
{ grayscale: true },
])
// Crop a region
const cropped = await client.images.url('photo.jpg', [
{ crop: { left: 100, top: 50, width: 400, height: 300 } },
])
// Flip, sharpen, adjust colors
const adjusted = await client.images.url('photo.jpg', [
{ flip: true },
{ sharpen: 2 },
{ modulate: { brightness: 1.2, saturation: 0.8 } },
])
// Disable auto-orient (enabled by default)
const raw = await client.images.url('photo.jpg', [
{ autoOrient: false },
{ resize: { width: 800 } },
])
// Custom output format (default is WebP at quality 90)
const jpeg = await client.images.url(
'photo.jpg',
[{ resize: { width: 800 } }],
{ format: 'jpeg', quality: 85 },
)Note:
url()usesnode:cryptofor signing and is intended for server-side use only. Tenant credentials are auto-fetched and cached on initialization.
Get a signed upload URL
Returns a CloudFront signed URL for direct upload (expires in 5 minutes). Useful for browser uploads where you don't want to expose your API key. The URL points to a CloudFront distribution (not S3 directly), so the underlying infrastructure is not exposed.
// Server: get the signed upload URL
const { uploadUrl, key } = await client.images.signUrl('photos/hero.jpg')
// Return uploadUrl to the browser
// Browser: upload directly
await fetch(uploadUrl, {
method: 'PUT',
body: file,
})Upload (Node.js)
Convenience method that gets a signed URL and uploads in one call. The file goes directly to CloudFront/S3 and never passes through the API. MIME type is auto-detected from file bytes (magic bytes for JPEG, PNG, GIF, WebP, BMP, AVIF, HEIC, HEIF) or file extension.
import { readFileSync } from 'node:fs'
const buffer = readFileSync('photo.jpg')
await client.images.upload(buffer, 'uploads/photo.jpg')List
const result = await client.images.list()
// { images: [{ key, size, lastModified }], nextCursor? }
// With pagination
const page = await client.images.list({
prefix: 'uploads/',
limit: 50,
cursor: result.nextCursor,
})Delete
await client.images.delete('uploads/photo.jpg')Metadata
Inspect image properties (dimensions, format, color space, etc.) without downloading the full image. The request goes through Luna, which extracts metadata using Sharp.
const meta = await client.images.metadata('photo.jpg')
// {
// width: 1920,
// height: 1080,
// format: 'jpeg',
// space: 'srgb',
// channels: 3,
// hasAlpha: false,
// density: 72,
// isProgressive: false,
// size: 204800,
// }Note:
metadata()usesnode:cryptofor signing and is intended for server-side use only.
API Keys
Manage API keys programmatically.
Create
const result = await client.keys.create({ name: 'Production' })
// { key: 'imk_...', prefix: 'imk_abcd', name: 'Production' }
// Save the key - it won't be shown againList
const keys = await client.keys.list()
// [{ id, name, keyPrefix, createdAt, lastUsedAt }]Revoke
await client.keys.revoke(keyId)Error handling
All API errors throw ImmaginError with the HTTP status and response body.
import { Immagin, ImmaginError } from '@immagin/client'
try {
await client.images.delete('missing.jpg')
} catch (err) {
if (err instanceof ImmaginError) {
console.log(err.status) // 404
console.log(err.message) // "Not found"
}
}Configuration
const client = new Immagin({
apiKey: 'imk_...', // Required
baseUrl: 'https://...', // Optional, defaults to https://gateway.immag.in
})License
MIT
