Installation
Requirements
| Peer dependency | Version | Required |
|---|---|---|
vue | ^3.0.0 | yes |
sharp | >=0.33.0 | only for the CLI (generate, placeholders) / Vite plugin / self-hosted server |
hazehash | >=0.1.1 | for hazehash placeholders (the preferred ones): decoding in the browser, and the default for generate, placeholders and the Vite plugin when installed |
thumbhash | >=0.1.0 | only for generate --thumbhash, placeholders --mode thumbhash and the Vite plugin's ?thumbhash/?vik build-time imports |
Everything that runs in the browser — decodeThumbHash(), the thumbhash prop on VImage, and the client-side encodeThumbHash()/encodeBlurhash() encoders — is a dependency-free, in-house implementation. sharp/thumbhash are only needed for the Node-side tooling that processes images ahead of time. hazehash is needed in the browser as well, to decode its placeholders: npm install hazehash.
Installation
npm install @macrulez/vue-image-kitPeer dependency:
npm install vue@>=3.0sharp, hazehash and thumbhash are optional peer dependencies. Install hazehash for the preferred placeholder (it is needed in the browser, so it is a regular dependency), and sharp (plus thumbhash, only for ThumbHash) if you use the CLI, the Vite plugin, or the self-hosted server:
npm install hazehash
npm install sharp --save-devQuick start — Vue 3
1. Register the plugin
// main.ts
import { createApp } from 'vue'
import { VImageKitPlugin } from '@macrulez/vue-image-kit'
import '@macrulez/vue-image-kit/style.css'
import App from './App.vue'
const app = createApp(App)
app.use(VImageKitPlugin)
app.mount('#app')After installation, <VImage> is available in all templates without importing, and v-lazy-img is registered as a global directive. The CSS import ships the small set of layout/placeholder classes <VImage> relies on — a handful of plain, overridable classes, not a design system.
2. Use the component
<template>
<VImage
src="/photo.jpg"
alt="Mountain landscape"
:width="1200"
:height="600"
blurhash="LEHV6nWB2yk8pyo0adR*.7kCMdnj"
/>
</template><VImage> is registered globally by the plugin. No import needed.
3. Or import explicitly
Skip the plugin and import only what you need — useful if you only want the directive, or a single composable, and want the bundler to tree-shake the rest away:
import {
VImageKitPlugin, // Vue plugin
VImage, // component
vLazyImg, // directive
useImage, // composable
useBlurhash, // canvas composable
useLazyLoad, // IO composable
decodeBlurhash, // standalone decoder
generateSrcset, // srcset utility
generateSizes, // sizes utility
} from '@macrulez/vue-image-kit'
import '@macrulez/vue-image-kit/style.css'<script setup lang="ts">
import { VImage } from '@macrulez/vue-image-kit'
import '@macrulez/vue-image-kit/style.css'
</script>
<template>
<VImage src="/photo.jpg" alt="My photo" />
</template>Quick start — Nuxt 3
1. Add the module to nuxt.config.ts
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@macrulez/vue-image-kit/nuxt'],
vueImageKit: {
breakpoints: {
sm: '(max-width: 640px)',
md: '(max-width: 1024px)',
},
},
})2. Use in pages and components — everything is auto-imported
<template>
<VImage
:src="{ avif: '/hero.avif', webp: '/hero.webp', fallback: '/hero.jpg' }"
alt="Hero image"
:width="1920"
:height="1080"
:widths="[640, 1024, 1920]"
sizes="100vw"
blurhash="LEHV6nWB2yk8pyo0adR*.7kCMdnj"
:lazy="true"
/>
</template><VImage>, v-lazy-img, all composables, and the CSS import from the Vue 3 example above are registered automatically — no imports needed. IntersectionObserver is activated only on the client — no hydration mismatch.