The Media-Processing Wrapper library provides a vendor-neutral contract for image and video operations: transform URLs, generate thumbnails, retrieve optimization metadata, and handle fallback behavior. The design system already ships media UI components (media.tsx, media-card.tsx), but there is no shared abstraction for the underlying media-processing service. This library bridges that gap so application code can request transforms, thumbnails, and metadata without coupling to Cloudinary, Imgix, or any specific provider.
Goals
Define a common MediaProvider interface for URL-based transforms (resize, crop, format conversion).
Provide a typed thumbnail-generation API with preset sizes and custom dimensions.
Expose optimization metadata (format, dimensions, file size, content type) through a typed schema.
Define fallback behavior when a provider is unavailable or a transform fails.
Ship a mock adapter for testing and a passthrough adapter for development.
Non-Goals
Implementing production Cloudinary, Imgix, or S3 adapters (shipped separately).
Client-side image editing or cropping UI.
Video transcoding or streaming.
CDN configuration or cache invalidation.
File upload (covered by the file-upload recipe).
Scope
In Scope
Area
Description
Media contract
MediaProvider interface for transformUrl, thumbnailUrl, getMetadata
Transform options
Typed options for width, height, crop mode, format, quality
Thumbnail presets
Named presets (sm, md, lg, xl) with configurable dimensions
Optimization metadata
MediaMetadata type: format, width, height, fileSize, contentType
Fallback behavior
Strategy pattern for unavailable providers: return original URL, placeholder, or throw
Mock adapter
In-memory adapter returning predictable URLs for testing
Passthrough adapter
Returns original URLs unchanged for local development
Unit tests
Full coverage of transforms, thumbnails, metadata, and fallback
Documentation
Storybook MDX docs with usage examples
Out of Scope
Area
Reason
Vendor-specific adapters
Shipped separately per provider
File upload
Covered by the file-upload recipe (item #78)
Video transcoding
Different concern requiring specialized infrastructure
CDN/cache configuration
Infrastructure concern
Client-side image editing
UI component concern
Users and Pain Points
User Groups
User
Description
Needs
Frontend developers
Engineers rendering images with transforms in UI components
A consistent API for generating transform URLs regardless of provider
Backend developers
Engineers generating thumbnail URLs in API responses
A typed thumbnail API with presets
Design system maintainers
Engineers maintaining media.tsx and media-card.tsx
A clean integration point for media processing in existing components
Pain Points
User
Pain Point
Impact
Frontend developers
Transform URL construction is scattered across components with provider-specific string manipulation
Provider lock-in; inconsistent URL patterns; hard to change providers
Backend developers
No shared thumbnail preset definitions; each service defines its own sizes
Inconsistent thumbnail dimensions across products
Design system maintainers
media.tsx has no standard way to request optimized images
Components render unoptimized images or duplicate optimization logic
Definitions
Term
Definition
Media provider
An object implementing MediaProvider that generates transform URLs for a specific service
Transform URL
A URL that instructs a media service to apply operations (resize, crop, format) to an image
Thumbnail preset
A named size configuration (e.g., sm: 150x150, md: 300x300)
Optimization metadata
Information about an image: format, dimensions, file size, content type
Fallback strategy
The behavior when a provider cannot process a request: return original URL, use placeholder, or throw
Passthrough adapter
A provider that returns URLs unchanged; useful for local development
Current State
Existing Behavior
The design system ships media.tsx and media-card.tsx components that accept image URLs directly. There is no abstraction for generating transform URLs, requesting thumbnails, or retrieving metadata.
Current Limitations
No shared interface for media transforms; each app constructs provider-specific URLs inline.
No thumbnail preset system; thumbnail sizes are hardcoded per feature.
No fallback behavior when a media provider is unavailable.
No mock adapter for testing image-dependent components.
Existing Workarounds
Developers construct Cloudinary or Imgix URLs manually with string concatenation.
Tests use static image URLs without testing transform logic.
Components accept full URLs, pushing transform responsibility to the consumer.
Proposed Solution
Summary
Ship a TypeScript library (@dmwd/media) exporting a MediaProvider interface, transform and thumbnail types, a metadata schema, fallback strategies, and mock/passthrough adapters.
Key Capabilities
MediaProvider interface with transformUrl, thumbnailUrl, and getMetadata methods.
PassthroughMediaProvider returning original URLs unchanged.
User Experience
Not directly applicable. Indirectly, users see faster-loading, correctly-sized images because the library enables consistent optimization.
Developer Experience
Developers inject a MediaProvider and call provider.transformUrl(src, { width: 800, format: 'webp' }) to get an optimized URL. Components like media.tsx can accept a provider prop or use a context. In tests, MockMediaProvider returns deterministic URLs. In local dev, PassthroughMediaProvider skips transforms.
Requirements
ID
Requirement
Priority
Notes
FR-001
The library must export a MediaProvider interface
Must
Core contract
FR-002
The library must export TransformOptions and ThumbnailPreset types
Must
Typed transforms
FR-003
The library must export a MediaMetadata type
Must
Optimization info
FR-004
The library must ship MockMediaProvider and PassthroughMediaProvider
Must
Testing and dev
FR-005
The library must support configurable fallback strategies
Must
Resilience
FR-006
The library should export a MediaContext React provider for component integration
Should
DX convenience
Priority Definitions
Priority
Meaning
Must
Required for this feature to ship.
Should
Important, but can be deferred if needed.
Could
Nice to have. Not required for initial release.
Functional Requirements
ID
Requirement
User Benefit
Priority
FUNC-001
transformUrl(src, options) returns a new URL with the requested transforms applied
Consistent transform API
Must
FUNC-002
thumbnailUrl(src, preset) returns a URL for the specified thumbnail preset
Easy thumbnail generation
Must
FUNC-003
getMetadata(src) returns MediaMetadata for the given source
Components can render placeholders with correct aspect ratios
Should
FUNC-004
Thumbnail presets include sm (150x150), md (300x300), lg (600x600), xl (1200x1200)
Consistent sizing across products
Must
FUNC-005
TransformOptions supports width, height, crop (fill, fit, cover), format (webp, avif, jpeg, png), and quality (1-100)
Full transform control
Must
FUNC-006
When fallback is 'original', return the unmodified source URL on provider failure
Graceful degradation
Must
FUNC-007
When fallback is 'placeholder', return a configurable placeholder URL on provider failure
Visual feedback that something went wrong
Must
FUNC-008
When fallback is 'throw', throw a typed MediaTransformError on provider failure
Callers can handle errors explicitly
Must
FUNC-009
MockMediaProvider.transformUrl returns a URL containing the transform parameters as query strings
Tests can assert on requested transforms
Must
Non-Functional Requirements
ID
Requirement
Category
Priority
NFR-001
Zero runtime dependencies (core library)
Maintainability
Must
NFR-002
React context provider is a separate entry point (@dmwd/media/react) to keep the core framework-agnostic
Compatibility
Must
NFR-003
All public types exported from package entry point
Maintainability
Must
NFR-004
transformUrl and thumbnailUrl must be synchronous (URL construction only)