Package Exports
- @bernierllc/validators-image-asset
- @bernierllc/validators-image-asset/dist/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@bernierllc/validators-image-asset) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
@bernierllc/validators-image-asset
Image asset validation for the BernierLLC validators ecosystem - validates accessibility, performance, and optimization.
Installation
npm install @bernierllc/validators-image-assetFeatures
- Accessibility: Validates alt text presence for screen readers
- Performance: Checks file sizes and image dimensions
- Optimization: Recommends modern formats (WebP, AVIF) and responsive images
- Responsive: Validates srcset usage for large images
- Type-Safe: Full TypeScript support with detailed interfaces
Usage
Basic Validation
import { validateImageAsset } from '@bernierllc/validators-image-asset';
const imageData = {
src: 'example.jpg',
alt: 'A beautiful sunset',
format: 'jpg',
size: 150000, // bytes
width: 1920,
height: 1080
};
const problems = await validateImageAsset(imageData);
problems.forEach(problem => {
console.log(`${problem.severity}: ${problem.message}`);
if (problem.suggestion) {
console.log(` Suggestion: ${problem.suggestion}`);
}
});Using Individual Rules
import {
missingAltText,
inefficientFormat,
excessiveFileSize
} from '@bernierllc/validators-image-asset';
import { createRuleContext } from '@bernierllc/validators-core';
import { createSharedUtils } from '@bernierllc/validators-utils';
const imageData = {
src: 'example.png',
alt: 'Example image',
format: 'png',
size: 250000
};
const sharedUtils = createSharedUtils();
const context = createRuleContext('image-asset', imageData, sharedUtils);
// Run specific rule
const check = missingAltText.create(context);
check(imageData);
const problems = context.getProblems();Integration with Validator Runner
import { imageAssetValidator } from '@bernierllc/validators-image-asset';
import { createRuleContext } from '@bernierllc/validators-core';
import { createSharedUtils } from '@bernierllc/validators-utils';
const imageData = {
src: 'hero.webp',
alt: 'Hero image',
format: 'webp',
size: 180000,
width: 1920,
height: 1080,
srcset: 'hero-320w.webp 320w, hero-640w.webp 640w, hero.webp 1920w'
};
const sharedUtils = createSharedUtils();
const context = createRuleContext('image-asset', imageData, sharedUtils);
const problems = await imageAssetValidator.validate(imageData, context);API Reference
validateImageAsset(imageData, utils?)
Validates image assets for accessibility, performance, and optimization.
Parameters:
imageData: ImageAssetData- The image data to validateutils?: SharedUtils- Optional shared utilities (created automatically if not provided)
Returns: Promise<Problem[]> - Array of validation problems
ImageAssetData
interface ImageAssetData {
src: string; // Image source URL (required)
alt?: string; // Alt text for accessibility
title?: string; // Optional title attribute
format?: string; // Image format (jpg, png, webp, avif, svg, etc.)
size?: number; // File size in bytes
width?: number; // Image width in pixels
height?: number; // Image height in pixels
srcset?: string; // Responsive image srcset
}Validation Rules
1. Missing Alt Text (image-asset/missing-alt-text)
Severity: Error Description: All images must have descriptive alt text for accessibility
// ❌ Invalid - Missing alt text
const invalid = {
src: 'example.jpg'
};
// ✅ Valid - Has alt text
const valid = {
src: 'example.jpg',
alt: 'A beautiful mountain landscape'
};2. Inefficient Format (image-asset/inefficient-format)
Severity: Error (legacy formats), Warning (acceptable formats) Description: Images should use modern formats like WebP or AVIF
// ❌ Error - Legacy format
const legacy = {
src: 'example.bmp',
alt: 'Example',
format: 'bmp'
};
// ⚠️ Warning - Acceptable but not optimal
const acceptable = {
src: 'example.jpg',
alt: 'Example',
format: 'jpg'
};
// ✅ Valid - Modern format
const modern = {
src: 'example.webp',
alt: 'Example',
format: 'webp'
};Format Categories:
- Modern (no warning): WebP, AVIF, SVG
- Acceptable (warning): PNG, JPG, JPEG, GIF
- Legacy (error): BMP, TIFF, TIF
3. Excessive File Size (image-asset/excessive-file-size)
Severity: Error (>1MB), Warning (>500KB), Info (>200KB) Description: Image files should be compressed to reduce load time
// ❌ Error - Too large (>1MB)
const tooLarge = {
src: 'example.jpg',
alt: 'Example',
size: 1.5 * 1024 * 1024
};
// ⚠️ Warning - Large (>500KB)
const large = {
src: 'example.jpg',
alt: 'Example',
size: 600 * 1024
};
// ℹ️ Info - Could be optimized (>200KB)
const moderate = {
src: 'example.jpg',
alt: 'Example',
size: 250 * 1024
};
// ✅ Valid - Optimized (<200KB)
const optimized = {
src: 'example.webp',
alt: 'Example',
size: 150 * 1024
};Size Thresholds:
- Recommended: < 200KB
- Maximum: < 500KB
- Critical: < 1MB
4. Excessive Dimensions (image-asset/excessive-dimensions)
Severity: Error (>4096x2160), Warning (>2560x1440) Description: Image dimensions should match display requirements
// ❌ Error - Excessive dimensions
const excessive = {
src: 'example.jpg',
alt: 'Example',
width: 5000,
height: 3000
};
// ⚠️ Warning - Large dimensions
const large = {
src: 'example.jpg',
alt: 'Example',
width: 3000,
height: 1600
};
// ✅ Valid - Reasonable dimensions
const reasonable = {
src: 'example.jpg',
alt: 'Example',
width: 1920,
height: 1080
};Dimension Thresholds:
- Recommended: ≤ 2560x1440 (4K displays)
- Critical: ≤ 4096x2160
5. Missing Srcset (image-asset/missing-srcset)
Severity: Warning Description: Large images should provide multiple sizes via srcset
// ⚠️ Warning - Large image without srcset
const noSrcset = {
src: 'example.jpg',
alt: 'Example',
width: 1920,
height: 1080
};
// ✅ Valid - Has responsive srcset
const withSrcset = {
src: 'example.jpg',
alt: 'Example',
width: 1920,
height: 1080,
srcset: 'example-320w.jpg 320w, example-640w.jpg 640w, example.jpg 1920w',
sizes: '(max-width: 640px) 100vw, 640px'
};
// ✅ Valid - Small image doesn't need srcset
const smallImage = {
src: 'icon.png',
alt: 'Icon',
width: 64,
height: 64
};Thresholds:
- Width > 800px OR Height > 600px: srcset recommended
Examples
Optimal Web Image
const optimalImage = {
src: 'hero.webp',
alt: 'Hero section showing our product dashboard',
format: 'webp',
size: 180 * 1024, // 180KB
width: 1920,
height: 1080,
srcset: 'hero-320w.webp 320w, hero-640w.webp 640w, hero-1280w.webp 1280w, hero.webp 1920w',
sizes: '(max-width: 768px) 100vw, (max-width: 1200px) 80vw, 1200px'
};
const problems = await validateImageAsset(optimalImage);
// Result: [] (no problems)Email-Safe Image
const emailImage = {
src: 'newsletter-banner.jpg',
alt: 'Monthly newsletter banner',
format: 'jpg',
size: 120 * 1024, // 120KB
width: 600,
height: 200
};
const problems = await validateImageAsset(emailImage);
// Result: [{ severity: 'warning', message: '...not optimal format...' }]
// JPG acceptable for email compatibilityIcon/Thumbnail
const icon = {
src: 'user-avatar.webp',
alt: 'User profile picture',
format: 'webp',
size: 8 * 1024, // 8KB
width: 150,
height: 150
};
const problems = await validateImageAsset(icon);
// Result: [] (no problems - small images don't need srcset)Integration Status
- Logger: Not applicable (primitive validator)
- Docs-Suite: Ready - Markdown documentation with code examples
- NeverHub: Not applicable (primitive validator)
Best Practices
1. Always Provide Alt Text
// ❌ Bad
<img src="product.jpg" />
// ✅ Good
<img src="product.jpg" alt="Red running shoes with white soles" />2. Use Modern Formats with Fallbacks
<picture>
<source srcset="image.avif" type="image/avif">
<source srcset="image.webp" type="image/webp">
<img src="image.jpg" alt="Fallback for older browsers">
</picture>3. Implement Responsive Images
<img
src="large.jpg"
srcset="small.jpg 320w, medium.jpg 640w, large.jpg 1280w"
sizes="(max-width: 640px) 100vw, 50vw"
alt="Responsive image example"
/>4. Optimize File Sizes
- Use compression tools (ImageOptim, Squoosh, Sharp)
- Target < 200KB for web images
- Use progressive JPEG for large photos
- Consider lazy loading for below-fold images
5. Match Dimensions to Display
- Don't serve 4K images for mobile devices
- Use srcset to provide appropriate sizes
- Consider device pixel ratio (2x, 3x for retina)
Testing
# Run tests
npm test
# Run tests with coverage
npm run test:coverage
# Run tests once (CI)
npm run test:runDevelopment
# Build the package
npm run build
# Watch mode for development
npm run dev
# Lint code
npm run lint
# Fix linting issues
npm run lint:fix
# Clean build artifacts
npm run cleanLicense
Copyright (c) 2025 Bernier LLC. All rights reserved.
See Also
- @bernierllc/validators-core - Core validation framework
- @bernierllc/validators-utils - Shared validation utilities
- @bernierllc/validators-a11y-contrast - Accessibility contrast validation
- @bernierllc/validators-web - Complete web page validation