Skip to content

Installation ​

Requirements ​

Peer dependencyVersionRequired
vue^3.0.0yes
sharp>=0.33.0only for the CLI (generate, placeholders) / Vite plugin / self-hosted server
hazehash>=0.1.1for hazehash placeholders (the preferred ones): decoding in the browser, and the default for generate, placeholders and the Vite plugin when installed
thumbhash>=0.1.0only 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 ​

bash
npm install @macrulez/vue-image-kit

Peer dependency:

bash
npm install vue@>=3.0

sharp, 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:

bash
npm install hazehash
npm install sharp --save-dev

Quick start — Vue 3 ​

1. Register the plugin

ts
// 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

vue
<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:

ts
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'
vue
<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

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

vue
<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.