{"id":15386696,"url":"https://github.com/zerodevx/svelte-img","last_synced_at":"2025-05-15T09:04:02.661Z","repository":{"id":57142927,"uuid":"297901748","full_name":"zerodevx/svelte-img","owner":"zerodevx","description":"High-performance responsive/progressive images for SvelteKit","archived":false,"fork":false,"pushed_at":"2024-11-25T16:12:25.000Z","size":13811,"stargazers_count":348,"open_issues_count":14,"forks_count":13,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-05-13T15:41:06.956Z","etag":null,"topics":["progressive-image-loading","responsive-images","svelte","sveltekit","vite-plugin"],"latest_commit_sha":null,"homepage":"https://zerodevx.github.io/svelte-img/","language":"Svelte","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zerodevx.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"zerodevx"}},"created_at":"2020-09-23T08:20:48.000Z","updated_at":"2025-05-05T09:53:32.000Z","dependencies_parsed_at":"2022-09-05T22:30:10.419Z","dependency_job_id":"8f70295c-1b15-4aad-a857-f50d000e4aab","html_url":"https://github.com/zerodevx/svelte-img","commit_stats":{"total_commits":117,"total_committers":4,"mean_commits":29.25,"dds":0.02564102564102566,"last_synced_commit":"1c3dc99795d1df089060db63f66e14f23cdd6269"},"previous_names":[],"tags_count":28,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zerodevx%2Fsvelte-img","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zerodevx%2Fsvelte-img/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zerodevx%2Fsvelte-img/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zerodevx%2Fsvelte-img/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zerodevx","download_url":"https://codeload.github.com/zerodevx/svelte-img/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254059508,"owners_count":22007768,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["progressive-image-loading","responsive-images","svelte","sveltekit","vite-plugin"],"created_at":"2024-10-01T14:50:12.734Z","updated_at":"2025-05-15T09:04:02.617Z","avatar_url":"https://github.com/zerodevx.png","language":"Svelte","funding_links":["https://github.com/sponsors/zerodevx"],"categories":["Svelte"],"sub_categories":[],"readme":"# svelte-img\n\n\u003e High-performance responsive/progressive images for SvelteKit.\n\nAutomatically transform local images into multiple widths and next-gen formats, then render a\nminimally invasive LQIP-included HTML representation into your SvelteKit project.\n\nIncludes special effects:\n\n- [x] Fade-in on image reveal\n- [x] Parallax vertical scroll effect\n\nHope you like cats. Demo: https://zerodevx.github.io/svelte-img/\n\n## Install\n\nInstall the package:\n\n```\n$ npm i -D @zerodevx/svelte-img\n```\n\nAdd `imagetools` plugin into your `vite.config.js`:\n\n```js\nimport { defineConfig } from 'vite'\nimport { sveltekit } from '@sveltejs/kit/vite'\nimport { imagetools } from '@zerodevx/svelte-img/vite'\n\nexport default defineConfig({\n  plugins: [sveltekit(), imagetools()]\n})\n```\n\nOptionally, to silence typescript\n[warnings](https://github.com/JonasKruckenberg/imagetools/issues/160) on image imports, create a new\nfile at `src/ambient.d.ts`:\n\n```js\n// Squelch warnings of image imports from your assets dir\ndeclare module '$lib/assets/*' {\n  var meta\n  export default meta\n}\n```\n\n### Under the hood\n\nLocal image transformations are delegated to the excellent\n[`vite-imagetools`](https://github.com/JonasKruckenberg/imagetools) with a custom `run` directive.\nThis preset generates optimised images with sensible defaults, including a `base64` low-quality\nimage placeholder.\n\nInvoke the preset with the `?as=run` query param:\n\n```js\nimport imageMeta from 'path/to/asset?as=run'\n```\n\n## Usage\n\nUse anywhere in your Svelte app:\n\n\u003c!-- prettier-ignore --\u003e\n```html\n\u003cscript\u003e\n  // Import original full-sized image with `?as=run` query param\n  import cat from '$lib/assets/cat.jpg?as=run'\n  import Img from '@zerodevx/svelte-img'\n\u003c/script\u003e\n\n\u003cImg class=\"cool kitty\" src=\"{cat}\" alt=\"Very meow\" /\u003e\n```\n\nThe image component renders into:\n\n```html\n\u003cpicture\u003e\n  \u003csource\n    type=\"image/avif\"\n    srcset=\"path/to/avif-480 480w, path/to/avif-1024 1024w, path/to/avif-1920 1920w\"\n  /\u003e\n  \u003csource\n    type=\"image/webp\"\n    srcset=\"path/to/webp-480 480w, path/to/webp-1024 1024w, path/to/webp-1920 1920w\"\n  /\u003e\n  \u003csource\n    type=\"image/jpeg\"\n    srcset=\"path/to/jpeg-480 480w, path/to/jpeg-1024 1024w, path/to/jpeg-1920 1920w\"\n  /\u003e\n  \u003cimg\n    class=\"cool kitty\"\n    width=\"1920\"\n    height=\"1080\"\n    loading=\"lazy\"\n    decoding=\"async\"\n    style=\"background: url(data:image/webp;base64,XXX) no-repeat center/cover\"\n    alt=\"Very meow\"\n    src=\"path/to/jpeg-1920\"\n  /\u003e\n\u003c/picture\u003e\n```\n\n## Features\n\n### Change default widths/formats\n\nBy default, `svelte-img` generates 9 variants of an original full-sized image - at `480/1024/1920`\nwidths in `avif/webp/jpg` formats; and a `16px webp/base64` low-quality image placeholder (LQIP).\n\nTo change this globally, edit your `vite.config.js`:\n\n```js\nimport ...\n\n// By default, `run` is set to 'w=480;1024;1920\u0026format=avif;webp;jpg' (9 variants)\nexport default defineConfig({\n  plugins: [\n    sveltekit(),\n    imagetools({\n      profiles: {\n        // Now we change `run` to generate 4 variants instead: 640/1280w in webp/jpg\n        run: new URLSearchParams('w=640;1280\u0026format=webp;jpg')\n      }\n    })\n  ]\n})\n```\n\n\u003e [!NOTE]  \n\u003e `runDefaultDirectives` is deprecated and will be removed in the next major; use `profiles`\n\u003e instead. When a profile is not used, behaviour falls back to standard `vite-imagetools`, which in\n\u003e turn take defaults from `defaultDirectives` as usual, so both can co-exist.\n\n### Profiles\n\nUse profiles to manage multiple defaults. Define in your `vite.config.js`:\n\n```js\nexport default defineConfig({\n  plugins: [\n    sveltekit(),\n    imagetools({\n      profiles: {\n        sm: new URLSearchParams('w=640\u0026format=webp;jpg'),\n        lg: new URLSearchParams('w=640;1280;1920\u0026format=webp;jpg')\n      }\n    })\n  ]\n})\n```\n\nThen invoke in your app:\n\n```js\nimport sm from '$lib/a/1.jpg?as=sm' // use `sm` profile\nimport lg from '$lib/a/2.jpg?as=lg' // use `lg` profile\nimport normal from '$lib/a/3.jpg?as=run'\n```\n\n### On a per-image basis\n\nWidths/formats can be applied to a particular image. From your `.svelte` file:\n\n\u003c!-- prettier-ignore --\u003e\n```html\n\u003cscript\u003e\n  // We override defaults to generate 4 variants: 720/1560w in webp/jpg\n  import src from '$lib/a/cat.jpg?w=720;1560\u0026format=webp;jpg\u0026as=run'\n  import Img from '@zerodevx/svelte-img'\n\u003c/script\u003e\n\n\u003cImg {src} alt=\"cat\" /\u003e\n```\n\n\u003e [!NOTE]  \n\u003e Order of `format` matters - the _last_ format is used as the fallback image.\n\nIf just **one** variant is generated, then only the `\u003cimg\u003e` tag renders, so:\n\n\u003c!-- prettier-ignore --\u003e\n```html\n\u003cscript\u003e\n  // Generate only 1 variant: 640x640 in jpg\n  import src from '$lib/a/cat.jpg?w=640\u0026h=640\u0026format=jpg\u0026as=run'\n  import Img from '@zerodevx/svelte-img'\n\u003c/script\u003e\n\n\u003cImg {src} alt=\"cat\" /\u003e\n```\n\nRenders into:\n\n```html\n\u003cimg\n  width=\"640\"\n  height=\"640\"\n  loading=\"lazy\"\n  decoding=\"async\"\n  style=\"background: url(data:image/webp;base64,XXX) no-repeat center/cover\"\n  alt=\"cat\"\n  src=\"path/to/jpg-640\"\n/\u003e\n```\n\n### Change LQIP width\n\nThe `run` directive takes an optional parameter that sets the LQIP's width. Using `?as=run` defaults\nto `16px` LQIP - functionally equivalent to `?as=run:16`. Increase for a higher quality LQIP (eg.\n`?as=run:32` for `32px` LQIP) at the expense of a larger inline `base64` (larger HTML size).\n\nTo disable LQIP, set `?as=run:0`.\n\nFor a dominant single-colour background, set `?as=run:1`, so:\n\n\u003c!-- prettier-ignore --\u003e\n```html\n\u003cscript\u003e\n  import src from '$lib/a/cat.jpg?as=run:1'\n  import Img from '@zerodevx/svelte-img'\n\u003c/script\u003e\n\n\u003c!-- Render img with dominant colour background --\u003e\n\u003cImg {src} alt=\"cat\" /\u003e\n```\n\nRenders into:\n\n\u003c!-- prettier-ignore --\u003e\n```html\n\u003cpicture\u003e\n  \u003csource ... /\u003e\n  \u003cimg ... style=\"background: #abcdef\" /\u003e\n\u003c/picture\u003e\n```\n\n### Other transformations\n\nThe full [repertoire](https://github.com/JonasKruckenberg/imagetools/blob/main/docs/directives.md)\nof transformation directives offered by\n[`vite-imagetools`](https://github.com/JonasKruckenberg/imagetools) can be used.\n\n\u003c!-- prettier-ignore --\u003e\n```html\n\u003cscript\u003e\n  // Generate all 9 variants at fixed 600px height\n  import src from '$lib/a/cat.jpg?h=600\u0026fit=cover\u0026normalize\u0026as=run'\n  import Img from '@zerodevx/svelte-img'\n\u003c/script\u003e\n\n\u003cImg {src} alt=\"cat\" /\u003e\n```\n\n### Responsive Image Sizes\n\nUse the `sizes` attribute to define media conditions that provide hints as to which image size to\nselect when those conditions are true. Read up more on\n[responsive images and the picture element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture).\n\n```html\n\u003cscript\u003e\n  import src from '$lib/a/cat.jpg?w=480;800\u0026as=run'\n  import Img from '@zerodevx/svelte-img'\n\u003c/script\u003e\n\n\u003c!-- \nWhen the viewport is \u003c=600px, tell the browser's image preloader that once \nthe CSS for our design has been parsed and applied, we expect the width of\nthe image in our design to be 480px. \n--\u003e\n\u003cimg {src} alt=\"cat\" sizes=\"(max-width: 600px) 480px, 800px\" /\u003e\n```\n\nRenders into:\n\n```html\n\u003cpicture\u003e\n  \u003csource\n    type=\"image/avif\"\n    sizes=\"(max-width: 600px) 480px, 800px\"\n    srcset=\"path/to/avif-480 480w, path/to/avif-800 800w\"\n  /\u003e\n  \u003csource\n    type=\"image/webp\"\n    sizes=\"(max-width: 600px) 480px, 800px\"\n    srcset=\"path/to/webp-480 480w, path/to/webp-800 800w\"\n  /\u003e\n  \u003csource\n    type=\"image/jpeg\"\n    sizes=\"(max-width: 600px) 480px, 800px\"\n    srcset=\"path/to/jpeg-480 480w, path/to/jpeg-800 800w\"\n  /\u003e\n  \u003cimg\n    alt=\"cat\"\n    width=\"800\"\n    height=\"600\"\n    loading=\"lazy\"\n    decoding=\"async\"\n    src=\"path/to/jpeg-800\"\n    style=\"background: url(data:image/webp;base64,XXX) center center / cover no-repeat;\"\n  /\u003e\n\u003c/picture\u003e\n```\n\n### Lazy loading\n\n`svelte-img` utilises the browser's native lazy loading capability by setting the `loading=\"lazy\"`\nattribute on the rendered `\u003cimg\u003e` tag by default. This is supported by\n[most modern browsers](https://caniuse.com/loading-lazy-attr). To load an image eagerly instead:\n\n\u003c!-- prettier-ignore --\u003e\n```html\n\u003cscript\u003e\n  import src from '$lib/a/cat.jpg?as=run'\n  import Img from '@zerodevx/svelte-img'\n\u003c/script\u003e\n\n\u003cImg {src} alt=\"cat\" loading=\"eager\" /\u003e\n```\n\n### Batch loading local images\n\nUse `Vite`'s `import.meta.glob` [feature](https://vitejs.dev/guide/features.html#glob-import).\n\n\u003c!-- prettier-ignore --\u003e\n```html\n\u003cscript\u003e\n  import Img from '@zerodevx/svelte-img'\n\n  const modules = import.meta.glob('$lib/a/cats/*.*', {\n    import: 'default',\n    eager: true,\n    query: { w: 640, h: 640, fit: 'cover', as: 'run' }\n  })\n  const images = Object.entries(modules).map((i) =\u003e i[1])\n\u003c/script\u003e\n\n{#each images as src}\n  \u003cImg {src} alt=\"cat\" /\u003e\n{/each}\n```\n\n### Remote images from an API\n\nUse the `svelte-img` component on its own by passing a `src` object, like so:\n\n\u003c!-- prettier-ignore --\u003e\n```html\n\u003cscript\u003e\nimport Img from '@zerodevx/svelte-img'\n\nconst src = {\n  sources: {\n    // Order is important; last format is fallback img\n    webp: 'path/to/480.webp 480w, ...', //srcset\n    jpeg: '...'\n  },\n  img: { src: 'path/to/img', w: 1920, h: 1080 },\n}\n\u003c/script\u003e\n\n\u003cImg {src} alt=\"cat\" /\u003e\n```\n\n### Blurred image placeholders\n\nNatively, browsers do already apply _some_ blur when displaying low resolution images. That's enough\nfor me, but you can apply your own using CSS.\n\n\u003c!-- prettier-ignore --\u003e\n```html\n\u003cscript\u003e\n  import Img from '@zerodevx/svelte-img'\n  import src from '$lib/a/cat.jpg?as=run'\n  import { onMount } from 'svelte'\n\n  let ref, loaded\n  onMount(() =\u003e {\n    if (ref.complete) loaded = true\n  })\n\u003c/script\u003e\n\n\u003cdiv class=\"wrap\"\u003e\n  \u003cImg {src} bind:ref on:load={() =\u003e (loaded = true)} /\u003e\n  \u003cdiv class=\"blur\" class:loaded /\u003e\n\u003c/div\u003e\n\n\u003cstyle\u003e\n  .wrap {\n    position: relative;\n    overflow: hidden;\n  }\n  .blur {\n    position: absolute;\n    inset: 0;\n    backdrop-filter: blur(20px);\n    pointer-events: none;\n  }\n  .loaded {\n    display: none;\n  }\n\u003c/style\u003e\n```\n\n## Special Effects\n\n### Fade-in on reveal\n\nReveal images with a fade-in effect (aka medium.com) when they are loaded **and** in the viewport.\n\n\u003c!-- prettier-ignore --\u003e\n```html\n\u003cscript\u003e\n  import src from '$lib/a/cat.jpg?as=run'\n  import { FxReveal as Img } from '@zerodevx/svelte-img'\n\u003c/script\u003e\n\n\u003cImg class=\"my-img\" {src} alt=\"cat\" /\u003e\n\n\u003cstyle\u003e\n  :global(.my-img) {\n    width: 640px;\n    height: 480px;\n    \n    /* These CSS vars (with their default values) are exposed */\n    --reveal-transform: scale(1.02);\n    --reveal-transition: opacity 1s ease-in, transform 0.8s ease-out;\n    --reveal-filter: blur(20px);\n  }\n\u003c/style\u003e\n```\n\n### Parallax\n\nApply a vertical parallax scrolling effect to an image, where `factor` is a decimal value between 0\nand 1, that controls how much slower the element scrolls, relative to the scrolling speed:\n\n- A value closer to 0 is faster, while a value closer to 1 is slower.\n- A value of 1 behaves normally.\n- A value of 0 effectively makes the element fixed on the page.\n\nThe default factor is `0.75`.\n\n\u003c!-- prettier-ignore --\u003e\n```html\n\u003cscript\u003e\n  import src from '$lib/a/cat.jpg?as=run'\n  import { FxParallax as Img } from '@zerodevx/svelte-img'\n\u003c/script\u003e\n\n\u003cImg class=\"my-img\" factor=\"0.5\" {src} alt=\"cat\" /\u003e\n\n\u003cstyle\u003e\n  :global(.my-img) {\n    width: 100%;\n    height: 28rem;\n  }\n\u003c/style\u003e\n```\n\n## Development\n\nLibrary is packaged via [SvelteKit](https://kit.svelte.dev/docs/packaging). Standard Github\n[contribution workflow](https://docs.github.com/en/get-started/quickstart/contributing-to-projects)\napplies.\n\n### Tests\n\nEnd-to-end testing via [Playwright](https://github.com/microsoft/playwright). To run tests\nheadlessly:\n\n```\n$ npm run test\n```\n\n## Changelog\n\nPlease refer to the [releases](https://github.com/zerodevx/svelte-img/releases) page.\n\n## License\n\nISC\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzerodevx%2Fsvelte-img","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzerodevx%2Fsvelte-img","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzerodevx%2Fsvelte-img/lists"}