@desource/image

中文文档
0.5.0发布于 2026/11/01MITTypeScriptES Module构建来源已验证近 30 天下载 1.7万

Framework-independent image optimization with responsive output, deployment-aware selection, presets, aliases, IPX, and dozens of built-in provider modules.

原始使用文档
文档目录16 节
  1. Why use the core package directly?
  2. Install
  3. Quick start
  4. What it generates
  5. Configuration
  6. Provider detection
  7. Source validation
  8. Responsive output
  9. Placeholders and picture fallbacks
  10. Providers
  11. Custom providers
  12. Provider-authoring utilities
  13. Framework integration kit
  14. Security
  15. Links
  16. License

DeSource Image
Framework-independent image optimization

@desource/image provides URL generation, responsive attributes, picture sources, configuration, presets, aliases, and provider tools for any JavaScript runtime.

npm version Coverage SonarCloud Ask Context7 Ask DeepWiki MIT license

AI-assisted development moves ideas into working products quickly. DeSource Image keeps image preparation inside that development loop. Add one suitable local or remote source, then control its output with typed image options.

Keep /img/hero.jpg instead of exporting hero-480.webp, hero-960.webp, and hero-1600.webp. The core engine generates provider URLs, responsive srcset data, <picture> sources, placeholders, and preload metadata, then applies presets, aliases, and source validation.

For MVPs and everyday product development, image quality becomes a code edit. Change quality: 80 to quality: 65 and keep the same source file, helper call, and URL in application code.

@desource/image powers the Angular, React, and Svelte packages, but it does not depend on a DOM or framework renderer. Use it anywhere that needs the same image URL and responsive-output rules: server templates, workers, metadata pipelines, emails, design systems, or custom components.

Provider configuration is optional. On Vercel, Netlify, or AWS Amplify, DeSource Image selects the platform image service from the deployment environment. Everywhere else, it falls back to the built-in IPX path. An explicit provider always wins.

Why use the core package directly?

Use @desource/image when image rules should live above a component:

  • Change image quality, format, crop, or responsive sizes in code while the source and filename stay unchanged.
  • Start with one suitable image and generate the widths and formats each screen needs.
  • Generate one URL or complete src, srcset, sizes, <picture>, placeholder, and preload data.
  • Let the deployment select Vercel, Netlify, or AWS Amplify, with IPX for local and other environments.
  • Share deployment detection, provider config, presets, aliases, and source rules across Angular, React, Svelte, workers, and Node scripts.
  • Create a callable $img helper for CSS, metadata, canvas, Open Graph images, email, or CMS previews.
  • Build a custom renderer without reimplementing width candidates, density candidates, format fallbacks, or preload metadata.
  • Author one typed provider and use it from every framework package.
  • Validate local and remote sources before they reach a public optimizer endpoint.

If you only render images through one framework package, install that framework package first. It already depends on @desource/image.

Install

npm install @desource/image

Quick start

import { createImage } from '@desource/image';

const image = createImage({
  quality: 76,
  screens: {
    sm: 640,
    md: 768,
    lg: 1024
  },
  presets: {
    avatar: {
      width: 96,
      height: 96,
      fit: 'cover',
      format: 'webp'
    }
  }
});

const url = image('/img/hero.jpg', {
  width: 800,
  format: 'webp'
});

const attrs = image.getAttrs({
  src: '/img/hero.jpg',
  alt: 'Mountain lake',
  width: 1600,
  height: 1000,
  sizes: '100vw md:760px',
  placeholder: true
});

const picture = image.getPicture({
  src: '/img/hero.jpg',
  alt: 'Mountain lake',
  width: 1600,
  height: 1000,
  formats: ['avif', 'webp'],
  fallbackFormat: 'jpg'
});

const avatarUrl = image.avatar('/people/ada.jpg');

The callable helper also exposes getImage, getSizes, getMeta, getPreloadLink, and one shortcut for every configured preset.

What it generates

APIOutput
image(src, modifiers)Optimized URL string.
getImage()Provider result with URL and optimization metadata.
getSizes()Normalized srcset, sizes, candidate widths, and descriptor data.
getAttrs()Native <img> attributes, placeholder URL, and placeholder class.
getPicture()Native <picture> data: ordered sources plus fallback image attrs.
getPreloadLink()Responsive <link rel="preload" as="image"> attributes.
getMeta()Image dimensions and metadata when a provider or runtime can load them.

Stateless helpers are available when a callable helper is not needed:

import { getImageAttrs, getImagePreloadLink, getImageSizes, getPictureAttrs } from '@desource/image';

const attrs = getImageAttrs({
  src: '/img/hero.jpg',
  alt: 'Mountain lake',
  width: 1600,
  height: 1000,
  sizes: '100vw md:760px',
  format: 'webp',
  quality: 76
});

Other public generators include generateSrcset, generatePictureSources, generateSizes, generateDensities, parseSizes, and parseDensities.

Configuration

import type { ImageConfig } from '@desource/image';
import { cloudinaryProvider } from '@desource/image/providers/cloudinary';

export const config: ImageConfig = {
  provider: 'cloudinary',
  baseURL: '/',
  quality: 76,
  format: 'webp',
  screens: {
    sm: 640,
    md: 768,
    lg: 1024,
    xl: 1280
  },
  densities: [1, 2],
  providerSizes: [320, 480, 640, 768, 1024, 1280, 1536],
  aliases: {
    media: 'https://assets.example.com'
  },
  domains: ['assets.example.com'],
  localPatterns: [{ pathname: '/img/**' }],
  remotePatterns: [{ protocol: 'https', hostname: '*.example.com', pathname: '/media/**' }],
  presets: {
    card: {
      width: 960,
      height: 640,
      sizes: '100vw md:480px',
      format: 'webp'
    }
  },
  providers: {
    cloudinary: cloudinaryProvider({ cloudName: 'demo' })
  },
  providerOptions: {
    cloudinary: {
      modifiers: { quality: 'auto' }
    }
  },
  onInvalidSource: 'warn'
};

resolveImageConfig(config) normalizes this once. createImageContext(config) returns the resolved config plus bound getImage, getImageAttrs, getPictureAttrs, getPreloadLink, and getMeta methods.

Provider detection

provider: 'auto' is the default. DeSource Image detects the deployment environment once and selects its image backend:

RuntimeProvider
Vercelvercel
AWS AmplifyawsAmplify
NetlifynetlifyImageCdn
Netlify Large MedianetlifyLargeMedia
Other / localipx

An explicit provider bypasses detection. React and Svelte Vite integrations can compile the result into client and SSR bundles, preventing provider drift during hydration.

Detection is based on the deployment, not the source URL. This lets the same local path use the platform optimizer in production and IPX during local development. The package does not read environment variables specific to DeSource Image or infer providers from browser hostnames.

Source validation

Use source controls when an optimizer endpoint should only transform known sources:

const config: ImageConfig = {
  domains: ['images.example.com'],
  localPatterns: [{ pathname: '/img/**' }],
  remotePatterns: [{ protocol: 'https', hostname: '*.example.com', pathname: '/media/**' }],
  onInvalidSource: 'throw'
};

Invalid-source policies:

  • throw: throw an error.
  • warn: log a warning and pass the source through.
  • passthrough: pass the source through without logging.

Patterns accept * for one path segment and ** for recursive matches.

Responsive output

Supported sizes forms:

100vw
sm:100vw md:50vw lg:400px
100vw md:760px

Object syntax is also accepted:

{
  sm: '100vw',
  md: '50vw',
  lg: 600
}

With sizes, output uses width descriptors and provider-size candidates. Without sizes, a known width uses density descriptors. Duplicate final URLs are removed, which matters for providers that normalize requested widths to configured breakpoints.

Placeholders and picture fallbacks

Placeholder values:

  • placeholder: true → [10, 10, 50, 3]
  • placeholder: 24 → width and height 24
  • placeholder: [24, 16, 40, 2] → custom width, height, quality, blur
  • placeholder: 'data:…' → use the string directly

Framework packages use the generated placeholderSrc and placeholderClass to show a small image until the full image decodes.

Picture output skips generated sources for SVG input, avoids duplicate formats, and keeps transparent-safe PNG fallback behavior.

Providers

The main entry includes a small default registry:

  • ipx
  • ipxStatic
  • vercel
  • awsAmplify
  • netlify
  • netlifyImageCdn
  • netlifyLargeMedia
  • none

Import all built-in provider modules only when required:

import { BUILT_IN_PROVIDER_NAMES, createBuiltInProviders } from '@desource/image/providers';

Prefer provider subpaths for application code:

import { cloudinaryProvider } from '@desource/image/providers/cloudinary';
import { imgixProvider } from '@desource/image/providers/imgix';
import { sanityProvider } from '@desource/image/providers/sanity';

Provider modules:

aliyun, appwrite, awsAmplify, builderio, bunny, caisy, cloudflare, cloudflareimages, cloudimage, cloudinary, contentful, contentstack, directus, edgeonePages, fastly, filerobot, filestack, flyimg, github, glide, gumlet, hygraph, imageengine, imagekit, imgix, imgproxy, ipx, ipxStatic, keycdn, netlify, netlifyImageCdn, netlifyLargeMedia, none, picsum, prepr, prismic, sanity, shopify, sirv, storyblok, strapi, strapi5, supabase, twicpics, umbraco, unsplash, uploadcare, vercel, wagtail, and weserv.

Provider behavior is parity-tested against a pinned Nuxt Image package where comparable behavior exists. The framework integrations remain native to Angular, React, and Svelte.

Custom providers

The provider contract is DeSource Image's own shape. It is intentionally small: a provider receives a normalized source, merged options, and an image context, then returns a URL.

import { configureProvider, defineProvider } from '@desource/image';

interface AcmeOptions {
  baseURL: string;
  token?: string;
}

const setup = defineProvider<AcmeOptions>({
  validateDomains: true,
  getImage(src, { modifiers, baseURL, token }, context) {
    const query = new URLSearchParams({
      src,
      width: String(modifiers.width ?? ''),
      quality: String(modifiers.quality ?? '')
    });

    if (token) query.set('token', token);

    return {
      url: `${baseURL}?${query}`,
      isOptimized: true
    };
  }
});

export const acmeProvider = configureProvider(
  setup,
  {
    baseURL: 'https://images.example.com/transform'
  },
  'acme'
);

Provider setup is memoized. Per-config providerOptions[name] are merged over configured defaults, and standard width/height/quality/format modifiers are merged last. The context exposes resolved options and a memoized $img helper.

Set acceptsOpaqueSource: true only for providers whose source is an asset ID rather than a path or URL. Set validateDomains: true when remote inputs must match configured domains or remotePatterns.

Provider-authoring utilities

The main entry exports reusable provider primitives:

  • defineProvider, configureProvider, resolveProviderRegistration
  • createMappedQueryProvider, mappedQueryURL, mappedModifiers
  • pathOperations, appendProviderModifiers, withStandardParams
  • providerBaseURL, sourceWithBase, sourcePath, joinURLParts
  • cleanColor, formatJpgValue, defaultFitValue
  • createMapper, createOperationsGenerator
  • appendQuery, stableModifiers, normalizeFormat, mimeForFormat

Framework integration kit

@desource/image/kit contains small helpers used by the framework packages:

import {
  isResolvedImageConfig,
  mergeClassNames,
  normalizeCrossorigin,
  stripUndefined,
  styleWithPlaceholder
} from '@desource/image/kit';

The subpath is limited to framework glue. Provider URL logic stays in the main package; rendering lifecycle stays in the framework packages.

Security

This package validates strings and generates URLs; it does not fetch remote bytes. IPX server integrations live in the framework packages and deny all remote domains by default.

For public optimizer endpoints, keep domains, remotePatterns, provider width lists, and quality lists aligned with the deployment configuration. Use narrow patterns to avoid transformation abuse.

License

MIT © 2026 DeSource Labs

版本与发布记录

@desource/image 共发布 6 个版本,首次发布于 2026/09/07;过去 12 个月发布了 6 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.5.0latest2026/11/0111 天前
0.4.02026/10/111 个月前
0.3.12026/10/011 个月前
0.3.02026/09/181 个月前
0.2.02026/09/151 个月前
0.1.02026/09/072 个月前

关于 @desource/image 的常见问题

@desource/image 是什么?

Framework-independent image optimization with responsive output, deployment-aware selection, presets, aliases, IPX, and dozens of built-in provider modules.

如何安装 @desource/image?

在项目目录运行 npm install @desource/image,或使用 pnpm add / yarn add / bun add。

@desource/image 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@desource/image 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@desource/image 可以商用吗?

@desource/image 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@desource/image 的下载量有多少?

根据 npm 官方下载统计,@desource/image 在 2026/10/12 – 2026/11/10 这 30 天内被下载 16,600 次,日均约 553 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@desource/image 还在维护吗?

最新版本 0.5.0 发布于 2026/11/01(11 天前);至今共发布 6 个版本,其中过去 12 个月发布了 6 个;首次发布于 2026/09/07。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。