{"id":49040325,"url":"https://github.com/mayur19/vue-image-parser","last_synced_at":"2026-04-19T14:38:21.559Z","repository":{"id":350322994,"uuid":"1206331222","full_name":"mayur19/vue-image-parser","owner":"mayur19","description":"Universal image rendering engine for Vue — supports JPEG, PNG, WebP, GIF, HEIC, AVIF with WASM fallback and zero main-thread blocking","archived":false,"fork":false,"pushed_at":"2026-04-16T20:53:58.000Z","size":30934,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-16T22:31:33.292Z","etag":null,"topics":["avif","heic","image-parser","typescript","vue","vue3","wasm","webp"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mayur19.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-09T20:08:03.000Z","updated_at":"2026-04-16T20:51:39.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/mayur19/vue-image-parser","commit_stats":null,"previous_names":["mayur19/vue-image-parser"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mayur19/vue-image-parser","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mayur19%2Fvue-image-parser","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mayur19%2Fvue-image-parser/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mayur19%2Fvue-image-parser/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mayur19%2Fvue-image-parser/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mayur19","download_url":"https://codeload.github.com/mayur19/vue-image-parser/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mayur19%2Fvue-image-parser/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32010196,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T20:23:30.271Z","status":"online","status_checked_at":"2026-04-19T02:00:07.110Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["avif","heic","image-parser","typescript","vue","vue3","wasm","webp"],"created_at":"2026-04-19T14:38:20.735Z","updated_at":"2026-04-19T14:38:21.550Z","avatar_url":"https://github.com/mayur19.png","language":"TypeScript","readme":"# vue-image-parser\n\n[![npm version](https://img.shields.io/npm/v/vue-image-parser.svg)](https://www.npmjs.com/package/vue-image-parser)\n[![CI](https://github.com/mayur19/vue-image-parser/actions/workflows/ci.yml/badge.svg)](https://github.com/mayur19/vue-image-parser/actions/workflows/ci.yml)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nUniversal image rendering engine for Vue 3 — supports JPEG, PNG, WebP, GIF, HEIC, and AVIF with WASM fallback and zero main-thread blocking.\n\n## Features\n\n- **Format Detection** — Binary signature detection (never file extensions) for JPEG, PNG, WebP, GIF, HEIC, HEIF, AVIF\n- **Capability Probing** — Pixel-verified native decode testing to determine browser support\n- **WASM Fallback** — Automatic fallback to libheif-js for HEIC/AVIF on unsupported browsers\n- **Web Worker Decoding** — Decode off the main thread via a pre-spawned worker pool\n- **EXIF Auto-Orient** — Automatic JPEG EXIF orientation handling\n- **GPU Rendering** — Uses ImageBitmap + drawImage for GPU-accelerated canvas rendering\n- **Vue 3 Integration** — `useImage` composable and `\u003cUniversalImage\u003e` component\n- **SSR Safe** — All browser APIs guarded for Nuxt/SSR environments\n- **Tree-Shakable** — ESM-only with `sideEffects: false`\n\n## Installation\n\n```bash\nnpm install vue-image-parser\n```\n\nHEIC/AVIF support via libheif-js is included out of the box.\n\n## Quick Start\n\n### Composable\n\n```vue\n\u003cscript setup\u003e\nimport { useImage } from 'vue-image-parser'\n\nconst { image, loading, error } = useImage('/photos/example.heic')\n\u003c/script\u003e\n\n\u003ctemplate\u003e\n  \u003cdiv v-if=\"loading\"\u003eLoading...\u003c/div\u003e\n  \u003cdiv v-else-if=\"error\"\u003e{{ error.message }}\u003c/div\u003e\n  \u003ccanvas v-else ref=\"canvas\" /\u003e\n\u003c/template\u003e\n```\n\n### Component\n\n```vue\n\u003cscript setup\u003e\nimport { UniversalImage } from 'vue-image-parser'\n\u003c/script\u003e\n\n\u003ctemplate\u003e\n  \u003cUniversalImage src=\"/photos/example.avif\" :max-dimension=\"1024\" /\u003e\n\u003c/template\u003e\n```\n\n### Plugin (global registration)\n\n```ts\nimport { createApp } from 'vue'\nimport { ImageParserPlugin } from 'vue-image-parser'\n\nconst app = createApp(App)\napp.use(ImageParserPlugin)\n```\n\n### Programmatic API\n\n```ts\nimport { loadImage, renderImage, detectFormat, disposeEngine } from 'vue-image-parser'\n\n// Load and decode\nconst decoded = await loadImage('/photo.heic', {\n  strategy: 'auto',    // 'auto' | 'native' | 'wasm'\n  maxDimension: 2048,\n  timeout: 30000,\n})\n\n// Render to canvas\nconst canvas = document.getElementById('canvas') as HTMLCanvasElement\nrenderImage(canvas, decoded, { fit: 'contain' })\n\n// Detect format without decoding\nconst format = detectFormat(buffer)\n\n// Clean up when done\ndecoded.dispose()\ndisposeEngine()\n```\n\n## API Reference\n\n### Core Functions\n\n| Function | Description |\n|----------|-------------|\n| `loadImage(source, options?)` | Load and decode an image from URL, File, Blob, or ArrayBuffer |\n| `renderImage(target, image, options?)` | Render a decoded image onto a canvas or HTML element |\n| `detectFormat(buffer)` | Detect image format from binary signature |\n| `detectFormatFromBlob(blob)` | Detect format from a Blob (reads first 64 bytes) |\n| `warmup(formats)` | Pre-initialize WASM codecs for given formats |\n| `disposeEngine()` | Release all resources (worker pool, codecs, registries) |\n\n### LoadOptions\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `strategy` | `'auto' \\| 'native' \\| 'wasm'` | `'auto'` | Decoding strategy |\n| `signal` | `AbortSignal` | — | Cancellation signal |\n| `timeout` | `number` | `30000` | Timeout in milliseconds |\n| `maxDimension` | `number` | — | Max width/height for downsampling |\n| `maxFileSize` | `number` | `104857600` | Max file size in bytes (100 MB) |\n| `autoOrient` | `boolean` | `true` | Auto-orient based on EXIF |\n| `onProgress` | `(p: number) =\u003e void` | — | Progress callback (0.0-1.0) |\n\n### RenderOptions\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `fit` | `'contain' \\| 'cover' \\| 'fill' \\| 'none' \\| 'scale-down'` | `'contain'` | Object-fit behavior |\n| `width` | `number` | image width | Target width |\n| `height` | `number` | image height | Target height |\n| `background` | `string` | — | Background color for letterboxing |\n| `dpr` | `number` | `devicePixelRatio` | Device pixel ratio |\n\n### Utilities\n\n| Function | Description |\n|----------|-------------|\n| `toDataURL(image, mimeType?)` | Convert decoded image to data URL |\n| `toBlobURL(image, mimeType?)` | Convert decoded image to blob URL |\n| `toImageBitmap(image)` | Convert decoded image to ImageBitmap |\n\n### Error Types\n\nAll errors extend `ImageParserError` with a machine-readable `code`:\n\n| Error | Code(s) | When |\n|-------|---------|------|\n| `FormatDetectionError` | `FORMAT_DETECTION_FAILED` | Unrecognized binary signature |\n| `CodecError` | `DECODE_FAILED`, `HEIC_DECODE_FAILED`, `AVIF_DECODE_FAILED` | Decode failure |\n| `FetchError` | `FETCH_FAILED`, `FILE_TOO_LARGE` | Network or file size error |\n| `TimeoutError` | `FETCH_TIMEOUT` | Operation exceeded timeout |\n| `AbortError` | `ABORTED` | Cancelled via AbortSignal |\n| `WorkerError` | `WORKER_CRASHED` | Web Worker failure |\n\n## Supported Formats\n\n| Format | Native | WASM Fallback |\n|--------|--------|---------------|\n| JPEG | All browsers | — |\n| PNG | All browsers | — |\n| GIF | All browsers | — |\n| WebP | All modern browsers | — |\n| HEIC/HEIF | Safari 17+ | libheif-js |\n| AVIF | Chrome 85+, Firefox 93+ | libheif-js |\n\n## Browser Compatibility\n\n- Chrome 85+\n- Firefox 93+\n- Safari 16.4+ (OffscreenCanvas)\n- Edge 85+\n\nOlder browsers work with reduced functionality (main-thread decoding, no OffscreenCanvas).\n\n## Memory Management\n\nDecoded images hold GPU resources (ImageBitmaps) and pixel buffers. Always dispose them when done:\n\n```ts\nconst decoded = await loadImage('/photo.heic')\ntry {\n  renderImage(canvas, decoded)\n} finally {\n  decoded.dispose()\n}\n```\n\nIn long-lived apps (SPAs), call `disposeEngine()` when your image-handling view is torn down to release the worker pool and codec instances:\n\n```ts\nimport { onBeforeUnmount } from 'vue'\nimport { disposeEngine } from 'vue-image-parser'\n\nonBeforeUnmount(() =\u003e {\n  disposeEngine()\n})\n```\n\nThe `useImage()` composable handles disposal automatically on component unmount.\n\n## Error Handling\n\nAll errors extend `ImageParserError` with a machine-readable `code` for programmatic handling:\n\n```ts\nimport { loadImage, ImageParserError, ErrorCodes } from 'vue-image-parser'\n\ntry {\n  const decoded = await loadImage(url)\n} catch (error) {\n  if (error instanceof ImageParserError) {\n    switch (error.code) {\n      case ErrorCodes.FORMAT_DETECTION_FAILED:\n        console.warn('Unsupported image format')\n        break\n      case ErrorCodes.FETCH_TIMEOUT:\n        console.warn('Image took too long to load')\n        break\n      case ErrorCodes.FILE_TOO_LARGE:\n        console.warn('Image exceeds size limit')\n        break\n      default:\n        console.error('Image error:', error.message)\n    }\n  }\n}\n```\n\n## SSR / Nuxt\n\nAll browser APIs are guarded behind `isBrowser()` checks. Use `onMounted()` or `\u003cClientOnly\u003e` to defer image operations:\n\n```vue\n\u003cscript setup\u003e\nimport { onMounted } from 'vue'\nimport { loadImage } from 'vue-image-parser'\n\nonMounted(async () =\u003e {\n  const decoded = await loadImage('/photo.heic')\n  // ...\n})\n\u003c/script\u003e\n```\n\n## Contributing\n\nContributions are welcome! Please read the [Contributing Guide](./CONTRIBUTING.md) and [Code of Conduct](./CODE_OF_CONDUCT.md) before submitting a PR.\n\n## License\n\n[MIT](./LICENSE)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmayur19%2Fvue-image-parser","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmayur19%2Fvue-image-parser","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmayur19%2Fvue-image-parser/lists"}