viucraft
v2.2.0
Published
Official JavaScript/TypeScript SDK for the Viucraft image processing & transformation API — zero-dependency, fully typed, dual ESM + CJS.
Maintainers
Readme
Viucraft JavaScript SDK
The official JavaScript/TypeScript SDK for Viucraft — the image processing & transformation API. Zero runtime dependencies, fully typed, dual ESM + CJS.
- 📦 npm:
viucraft—npm install viucraft - 📚 Docs: https://viucraft.com/docs
- 🧩 Source: https://github.com/BStorm-IT/viucraft-js
Installation
npm install viucraftOr using yarn:
yarn add viucraftBasic Usage
import { ViucraftClient } from 'viucraft';
// Initialize client with your API key
const client = new ViucraftClient({
apiKey: 'your-api-key-here',
// For paid plans with custom domain
subdomain: 'your-subdomain', // Optional, for paid plans
});
// Upload an image
const uploadResult = await client.uploadImage(fileObject);
const imageId = uploadResult.image_id;Configuration
The client supports several configuration options:
const client = new ViucraftClient({
apiKey: 'your-api-key-here',
subdomain: 'your-subdomain', // Optional, for paid plans
baseUrl: 'https://api.viucraft.com', // Optional, custom API URL
accountId: 'acc_123', // Optional, for free plans
timeout: 30000, // Optional, request timeout in ms (default: 30000)
enforceHttps: true, // Optional, warn on HTTP URLs (default: true)
retry: { // Optional, retry config for 429 responses
maxRetries: 3, // Max retry attempts (default: 3)
initialDelayMs: 1000, // Initial backoff delay (default: 1000)
maxDelayMs: 30000, // Maximum backoff delay (default: 30000)
backoffMultiplier: 2, // Exponential backoff multiplier (default: 2)
},
// retry: false, // Set to false to disable retries
});You can also update certain config values after construction:
client.updateConfig({ apiKey: 'new-api-key' });
client.updateConfig({ timeout: 5000 });
client.updateConfig({ subdomain: null }); // clear subdomain → use the free-tier URLKeeping URLs correct across plan changes
A client caches the subdomain / accountId it was built with, so a long-lived instance
can keep generating subdomain URLs after a customer downgrades to free (which deactivates
their subdomain). Call resolveEndpoint() to fetch the account's current configuration from
the API and rebuild URLs against the correct base:
// Re-sync the client with the account's current plan/subdomain.
await client.resolveEndpoint();
// After a paid→free downgrade, image URLs now use the shared /free/acc_* form automatically.
// Or resolve up front when constructing:
const client = await ViucraftClient.create({ apiKey: 'your-api-key-here' });Note: even without an SDK upgrade, requests to a deactivated subdomain are transparently redirected (HTTP 302) to the free-tier URL server-side, so previously-published image URLs keep working.
Chainable API (Recommended)
The SDK supports a chainable API for creating image URLs with transformations:
// Create a resized image URL
const resizedUrl = client.image(imageId)
.resize(300, 200)
.toURL();
// Create a complex transformation with multiple operations
const complexUrl = client.image(imageId)
.resize(500, 300)
.brightness(1.2)
.contrast(1.1)
.sharpen(0.8)
.grayscale()
.setFormat('webp')
.toURL();
// Create a thumbnail with cropping strategy
const thumbnailUrl = client.image(imageId)
.thumbnail(150, 150, 'entropy')
.toURL();Chainable Methods
.resize(width, height, [scale])- Resize an image.crop(left, top, width, height)- Crop an image.rotate(angle, [background])- Rotate an image.brightness(factor)- Adjust brightness (0-10).contrast(factor)- Adjust contrast (0-10).grayscale()- Convert to grayscale.invert()- Invert colors.blur([sigma])- Apply blur effect.sharpen([sigma])- Sharpen the image.emboss()- Apply emboss effect.median([size])- Apply median filter.thumbnail(width, height, [crop])- Create a thumbnail.smartCrop(width, height)- Apply smart cropping.flip(direction)- Flip image ('horizontal', 'vertical', 'h', 'v').quality(value)- Set output quality (1-100).setFormat(format)- Set output format ('jpg', 'png', 'webp').useShort([boolean])- Use short URL format.getInstructions()- Get a copy of current processing instructions.toURL()- Generate the final URL
Error Handling
The SDK uses a custom error hierarchy for structured error handling:
import {
ViucraftError,
ViucraftValidationError,
ViucraftRateLimitError,
ViucraftNetworkError,
} from 'viucraft';
try {
const result = await client.uploadImage(file);
} catch (error) {
if (error instanceof ViucraftRateLimitError) {
// Rate limited - retryAfter tells you how long to wait
console.log(`Rate limited. Retry after ${error.retryAfter} seconds`);
console.log('Rate limit info:', error.rateLimit);
} else if (error instanceof ViucraftValidationError) {
// Client-side validation failure
console.log(`Invalid parameter: ${error.parameterName}`);
} else if (error instanceof ViucraftNetworkError) {
// Connection failure or timeout
console.log('Network error:', error.message);
} else if (error instanceof ViucraftError) {
// General API error
console.log(`API error ${error.status}: ${error.message}`);
console.log('Error code:', error.code);
}
}All error classes extend ViucraftError, which extends Error:
ViucraftError- Base class withcode,status,rateLimit,responseDataViucraftValidationError- Client-side validation errors withparameterNameViucraftRateLimitError- HTTP 429 errors withretryAfter(seconds)ViucraftNetworkError- Connection/timeout failures
Rate Limiting
The SDK automatically retries requests that receive HTTP 429 (Too Many Requests) responses using exponential backoff. When available, it respects the Retry-After and X-RateLimit-Reset response headers.
Default retry behavior: up to 3 retries with 1s initial delay and 2x backoff multiplier. Configure or disable via the retry option:
// Custom retry config
const client = new ViucraftClient({
apiKey: 'your-key',
retry: { maxRetries: 5, initialDelayMs: 500 },
});
// Disable retries
const client = new ViucraftClient({
apiKey: 'your-key',
retry: false,
});Legacy API (Deprecated)
The SDK still supports the legacy API for backward compatibility:
// Create an image URL with processing instructions
const imageUrl = client.buildImageUrl(imageId, {
resize: { width: 300, height: 200 },
grayscale: true,
brightness: 1.2
});
// Or use the short format
const thumbnailUrl = client.buildImageUrl(imageId, 'thumb-300-200');Other Operations
// Delete an image
const deleteResult = await client.deleteImage(imageId);
// Get image information
const imageInfo = await client.getImageInfo(imageId);
// List images (paginated)
const imagesList = await client.listImages(1, 20);Available Image Operations
The SDK supports all image operations available in the Viucraft API:
- Resize - Resize an image to specific dimensions
- Crop - Crop an image at specific coordinates
- Rotate - Rotate an image by a specified angle
- Brightness - Adjust image brightness
- Contrast - Adjust image contrast
- Grayscale - Convert image to grayscale
- Thumbnail - Create a thumbnail with intelligent resizing
- SmartCrop - Intelligent cropping that preserves important parts of the image
- Blur - Apply Gaussian blur
- Sharpen - Sharpen the image
- Invert - Invert the image colors
- Emboss - Apply emboss effect
- Median - Apply median filter for noise reduction
- Flip - Flip image horizontally or vertically
- Quality - Set output quality (1-100)
Security Notes
- Never embed API keys in client-side (browser) code. API keys should only be used in server-side environments. For browser usage, proxy requests through your backend.
- The SDK warns when using HTTP instead of HTTPS, since API keys sent over HTTP can be intercepted.
- Use
getMaskedApiKey()for safe logging:client.getMaskedApiKey()returnsabcd****efgh.
Migration from 1.0
Breaking Changes
uploadImage()now throws on error instead of returning{ status: 'error', error_message: '...' }. Wrap calls in try/catch.deleteImage()now throws on error instead of returning{ success: false, message: '...' }.
Before (1.0):
const result = await client.uploadImage(file);
if (result.status === 'error') {
console.error(result.error_message);
}After (1.1):
try {
const result = await client.uploadImage(file);
// result.status is always 'success' here
} catch (error) {
if (error instanceof ViucraftError) {
console.error(error.message);
}
}Examples
Basic Example
// Upload an image and create a thumbnail
try {
const uploadResult = await client.uploadImage(fileObject);
if (uploadResult.image_id) {
const thumbnailUrl = client.image(uploadResult.image_id)
.thumbnail(200, 200, 'entropy')
.grayscale()
.toURL();
// Use the thumbnail URL in your application
document.getElementById('preview').src = thumbnailUrl;
}
} catch (error) {
console.error('Upload failed:', error.message);
}Advanced Example
// Create a complex image processing chain
const processedImageUrl = client.image(imageId)
.resize(800, 600)
.brightness(1.1)
.contrast(1.2)
.sharpen(0.7)
.quality(90)
.setFormat('webp')
.toURL();
// The URL can be used directly in img tags
const img = document.createElement('img');
img.src = processedImageUrl;
document.body.appendChild(img);Documentation
For detailed documentation and examples, see the API Reference.
License
MIT
