PHPackages                             wazum/thumb-hash - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Image &amp; Media](/categories/media)
4. /
5. wazum/thumb-hash

ActiveTypo3-cms-extension[Image &amp; Media](/categories/media)

wazum/thumb-hash
================

TYPO3 extension for generating ThumbHash for images. Enhance user experience with fast image thumbnails.

1.1.0(7mo ago)61.4k↓21.9%2[1 PRs](https://github.com/wazum/thumb-hash/pulls)GPL-2.0-or-laterPHPPHP ^8.2CI passing

Since Sep 9Pushed 5mo agoCompare

[ Source](https://github.com/wazum/thumb-hash)[ Packagist](https://packagist.org/packages/wazum/thumb-hash)[ RSS](/packages/wazum-thumb-hash/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (6)Versions (3)Used By (0)

TYPO3 *ThumbHash* Extension
===========================

[](#typo3-thumbhash-extension)

[![CI](https://github.com/wazum/thumb-hash/actions/workflows/ci.yml/badge.svg)](https://github.com/wazum/thumb-hash/actions/workflows/ci.yml)[![PHP](https://camo.githubusercontent.com/9b176cf17d528e7868bee16c169aa98656fc2aed2bb513abdaf50cddec54afbe/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e32253230253743253230382e332d626c75652e737667)](https://www.php.net/)[![TYPO3](https://camo.githubusercontent.com/cfea29f55fd4bf87d4727e5ce7640baaad6274047c8051a6c4ba85290b9e3565/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5459504f332d31322e3425323025374325323031332e342d6f72616e67652e737667)](https://typo3.org/)[![License](https://camo.githubusercontent.com/77e900ae34f8da9ccccc42662fce61a94ab07ddbfe3f7d066178e824f3673dbd/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d47504c25323076322d626c75652e737667)](LICENSE)

Enhance user experience with fast, ultra-compact, and appealing image placeholders for TYPO3 websites.

[ThumbHash](https://evanw.github.io/thumbhash/) creates placeholders in **just ~28 bytes** ✨ that accurately represent your images while they load. It seamlessly enhances native lazy loading (`loading="lazy"`) by showing a meaningful preview until the image appears.

Benefits at a Glance
--------------------

[](#benefits-at-a-glance)

- Show a soft, on‑brand preview while images load — no more empty space.
- No extra image files, no extra requests — just a few characters embedded alongside your image.
- Works automatically with your existing TYPO3 images, templates and lazy loading (`loading="lazy"` or JS libraries).

### Perfect For

[](#perfect-for)

- Product listings and category grids (e‑commerce)
- News teasers and card layouts (publishers)
- Portfolios, galleries and hero images (agencies/creatives)
- Landing pages with many visuals (marketing)
- Any site where images load over slow networks or on mobile

### What Makes It Great

[](#what-makes-it-great)

- **Tiny &amp; Fast:** About 25–35 bytes per image; nothing else to download.
- **Smooth UX:** Beautiful blurred preview that matches the final image and prevents layout shift.
- **Automatic:** Generated on upload and for every cropped/processed variant.
- **Drop‑in:** A single Fluid attribute adds the placeholder to your images.

Quick Start
-----------

[](#quick-start)

```
composer require wazum/thumb-hash
```

```

```

Output: ``

That's it! Hashes are generated automatically on upload. Add the [frontend JavaScript](#frontend-implementation) for the blur effect.

Use Cases
---------

[](#use-cases)

- **E‑commerce lists:** Give shoppers instant visual context while product images stream in.
- **News portals:** Keep article cards readable without jarring pop‑in as thumbnails load.
- **Portfolios &amp; galleries:** Maintain composition and color feel while high‑res shots load.
- **Hero banners:** Avoid a blank hero on slow connections; show a pleasant preview immediately.
- **Long pages with lazy images:** Reduce perceived wait time as users scroll.
- **Low‑bandwidth audiences:** Improve mobile experience in regions with spotty coverage.

Why ThumbHash?
--------------

[](#why-thumbhash)

### The Problem

[](#the-problem)

When images load on slow connections, users see:

- Empty gray rectangles that suddenly pop into images
- Layout shifts as images load with different aspect ratios
- Poor perceived performance

### The Solution

[](#the-solution)

ThumbHash generates tiny placeholders that:

- Show a blurred preview of the actual image
- Preserve the exact aspect ratio
- Fade smoothly into the loaded image
- Work without additional network requests

Visual Demo
-----------

[](#visual-demo)

[![Original Image](Documentation/lightning-strikes.jpg)](Documentation/lightning-strikes.jpg)

**↓** *Encoded to just 28 bytes (on the server)* **↓**

`3OcRJYB4d3h/iIeHeEh3eIhw+j3A`

**↓** *Decoded to placeholder (on the client)* **↓**

[![ThumbHash Placeholder](Documentation/lightning-strikes-thumbhash.png)](Documentation/lightning-strikes-thumbhash.png)

What your users will see while the image is loading:

[![](Documentation/lightning-strikes-thumbhash.png)](Documentation/lightning-strikes-thumbhash.png)

From a 200 KB image → to 28 characters → back to a beautiful placeholder that preserves colors, composition, and aspect ratio.

[**Try the interactive demo with your own images →**](https://evanw.github.io/thumbhash/#demo)

Photo by Frank Cone:

How It Compares
---------------

[](#how-it-compares)

SizeQualityNetwork RequestsAspect Ratio**ThumbHash**~25-35 bytes¹ExcellentNonePreservedBlurHash (alternative)20-30 chars²GoodNoneNot preservedLQIP (webp)150-350 bytes³Good1 per imagePreservedSolid Color~7 bytesPoorNoneNot preserved¹[ThumbHash documentation](https://evanw.github.io/thumbhash/)
²[BlurHash repository](https://github.com/woltapp/blurhash)
³[LQIP Modern benchmarks](https://github.com/transitive-bullshit/lqip-modern)

Features
--------

[](#features)

- **Automatic generation** — Hashes are created when images are uploaded
- **`ProcessedFile` support** — Each cropped variant gets its own placeholder
- **Database storage** — Hashes are stored in `sys_file_metadata` and `sys_file_processedfile`
- **Multiple processors** — Supports both GD and ImageMagick
- **ViewHelper integration** — Simple Fluid template integration
- **Event-driven** — Responds to TYPO3 file events automatically
- **Console command** — Process existing files via CLI with `thumbhash:generate`
- **Scheduler support** — Run batch processing as scheduled tasks
- **Minified JavaScript** — Ready-to-use decoder included

FAQ
---

[](#faq)

- **Does this slow down my site?** No. The hash is embedded as a tiny string — there are no extra requests. Images load as usual; users just see a better preview.
- **What if JavaScript is disabled?** Images still load normally. The JS only paints the blurred background until the image finishes loading.
- **Does this replace lazy loading?** No. Keep using `loading="lazy"` (or your lazy‑loading library). ThumbHash complements it by filling the visual gap with a matching preview while the image is deferred.
- **Does this affect SEO or accessibility?** No. Your `alt` text, dimensions and markup remain unchanged; placeholders help prevent layout shifts that can harm Core Web Vitals.
- **Which image types are supported?** JPEG, PNG, GIF by default; you can adjust allowed MIME types. Works regardless of your output format (e.g., WebP/AVIF delivery).
- **Will it work with cropped images and variants?** Yes. Every processed variant gets its own accurate placeholder.
- **Can I turn it off for certain folders?** Yes. Use configuration to exclude folders for original files while still handling processed variants.

Installation
------------

[](#installation)

```
composer require wazum/thumb-hash
```

The extension works out of the box with sensible defaults. After installation:

1. Go to **Admin Tools &gt; Maintenance &gt; Analyze Database Structure** to add the required database fields
2. New uploads generate ThumbHash values automatically
3. Existing images can be processed using the [command line tool](#command-line-tool)
4. Configuration can be adjusted in the **Admin Tools &gt; Settings &gt; Extension Configuration** section if needed

Usage
-----

[](#usage)

### In Fluid Templates

[](#in-fluid-templates)

The extension globally registers the `thumbhash` namespace, so you can use it immediately:

```

```

If you prefer explicit namespace imports (optional, since it's globally registered):

```

```

This generates the following HTML output:

```

```

The ViewHelper works with `File`, `FileReference`, and `ProcessedFile` objects.

### Command Line Tool

[](#command-line-tool)

Generate ThumbHash values for existing files that don't have them yet:

```
# Process up to 100 files (default)
vendor/bin/typo3 thumbhash:generate

# Process a specific number of files
vendor/bin/typo3 thumbhash:generate --limit=500

# Process all files (use with caution on large installations)
vendor/bin/typo3 thumbhash:generate --limit=999999
```

The command:

- Processes both original files and their processed variants
- Respects the extension configuration (allowed MIME types, excluded folders)
- Shows progress for each processed file
- Skips files that already have hashes
- Can be run as a **scheduler task** for automatic processing

**Scheduler Configuration:**

1. Go to **System &gt; Scheduler**
2. Create a new task of type "Execute console commands"
3. Select **thumbhash:generate** from the dropdown
4. Set options (e.g., `--limit=50`)
5. Configure the schedule (e.g., daily at night)

### Frontend Implementation

[](#frontend-implementation)

**Note:** ThumbHash uses progressive enhancement — images load normally even with JavaScript disabled. The placeholder effect is a visual enhancement only. It also complements native lazy loading and JS lazy‑loading libraries by providing an instant visual preview while the browser defers the image.

The extension includes a minified ThumbHash decoder at [`Resources/Public/JavaScript/thumb-hash.min.js`](Resources/Public/JavaScript/thumb-hash.min.js) that provides the `thumbHashToDataURL` function.

#### Add to your PAGE setup

[](#add-to-your-page-setup)

Add your initialization code after the page (and all the images):

```
page {
    includeJS {
        thumbHash = EXT:thumb_hash/Resources/Public/JavaScript/thumb-hash.min.js
        thumbHash.forceOnTop = 1
    }

    10 = FLUIDTEMPLATE
    10 {
       …
    }

    20 = TEXT
    20.value (

    document.querySelectorAll('[data-thumbhash]').forEach(function(img) {
        var hash = img.dataset.thumbhash;
        if (!hash) return;
        var bytes = new Uint8Array(atob(hash).split('').map(function(c) {
            return c.charCodeAt(0);
        }));
        var dataUrl = thumbHashToDataURL(bytes);
        img.style.background = 'url(' + dataUrl + ') center/cover no-repeat';
        img.addEventListener('load', function() {
            img.style.background = '';
        }, { once: true });
    });

    )
}

```

The code above is the most straight-forward integration example. Of course, you can use any other kind of integrating the required JavaScript to your project, like:

- Placing the code in your main layout Fluid file using the [``](https://docs.typo3.org/permalink/t3viewhelper:typo3-fluid-asset-script)(or `` when using vite integration).
- When using EXT:contentblocks, adding that Code with the mentioned ViewHelpers into the specific content block fluid file.

These approaches are recommended if your project uses CSP (Content-Security-Policy) to block inline JavaScript execution. You need to use proper prioritization so that the code above is executed as one of the first JavaScript events in your code.

#### Using Vite, Webpack, or other bundlers

[](#using-vite-webpack-or-other-bundlers)

**Important:** The bundled `thumb-hash.min.js` file uses a global script pattern and is **not compatible with ES module imports**. If you try to import it directly in Vite or other modern bundlers, you'll get an error like `"can't access property 'thumbHashToDataURL', r is undefined"`.

For projects using modern JavaScript bundlers, install the official ThumbHash npm package instead:

```
npm install thumbhash
```

Then create your initialization module:

```
// assets/js/thumbhash-init.ts
import { thumbHashToDataURL } from 'thumbhash';

document.querySelectorAll('[data-thumbhash]').forEach((img) => {
    const hash = img.dataset.thumbhash;
    if (!hash) return;

    const bytes = Uint8Array.from(atob(hash), (c) => c.charCodeAt(0));
    const dataUrl = thumbHashToDataURL(bytes);

    img.style.background = `url(${dataUrl}) center/cover no-repeat`;
    img.addEventListener('load', () => {
        img.style.background = '';
    }, { once: true });
});
```

This approach gives you:

- Proper ES module imports
- TypeScript type definitions
- Tree-shaking support
- Upstream library updates

Configuration
-------------

[](#configuration)

Extension configuration allows you to customize:

- **autoGenerate** — Enable/disable automatic generation (default: true)
- **allowedMimeTypes** — Supported MIME types (default: image/jpeg,image/jpg,image/png,image/gif)
- **excludedFolders** — Folders to skip for original files only (default: fileadmin/*processed*/,fileadmin/*temp*/)
    - Note: Processed file variants are always handled regardless of folder exclusions, ensuring cropped/resized images get their own accurate placeholders
- **imageProcessor** — Select processing backend: `auto` | `imagick` | `gd`
    - `auto` tries `imagick` → `gd`
    - Explicit choices have no fallback. Ensure the dependency exists (e.g., PHP Imagick extension for `imagick`).
    - Set via Install Tool: Admin Tools → Settings → Extension Configuration → `thumb_hash`or in configuration: `$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['thumb_hash']['imageProcessor'] = 'gd';`

Architecture
------------

[](#architecture)

### Storage

[](#storage)

- Original images: `sys_file_metadata.thumb_hash`
- Processed images: `sys_file_processedfile.thumb_hash`

### Event Listeners

[](#event-listeners)

- `AfterFileAddedEvent` — Generate for new uploads (respects folder exclusions)
- `AfterFileProcessingEvent` — Generate for processed variants (ignores folder exclusions)
- `AfterFileReplacedEvent` — Regenerate when files change (respects folder exclusions)

### Image Processing

[](#image-processing)

Processor selection respects the `imageProcessor` setting. With `auto`, priority is:

1. **Imagick (PHP extension)** — High quality, good alpha handling, efficient memory usage
2. **GD** — Ubiquitous fallback

**Important: Memory Considerations**

- **Imagick is strongly recommended** for production use, especially with large images
- GD must load entire images into memory before processing, which can cause memory exhaustion on high-resolution images
- Imagick uses optimized decoding hints to load images at reduced resolution, significantly reducing memory usage
- The extension includes safeguards (20MB file size limit, dimension limits for GD), but Imagick handles edge cases more gracefully
- If using GD with large images, ensure adequate PHP memory\_limit (512MB+ recommended)

Why no CLI (GraphicalFunctions) support?

- External process overhead is large (hundreds of ms/iter), dominated by process spawn and TXT I/O.
- Placeholder generation downsamples to ≤100px; color/alpha precision gains from CLI paths are negligible compared to GD/Imagick.
- Benchmarks showed GD/Imagick are orders of magnitude faster with indistinguishable results at this size.

User Experience Benefits
------------------------

[](#user-experience-benefits)

ThumbHash enhances perceived performance:

- **Eliminates layout shift** — Placeholders reserve the exact space needed, preventing content jumping
- **Instant visual feedback** — Users see a meaningful preview immediately instead of empty rectangles
- **Smoother loading experience** — Images fade in gracefully from their blurred placeholders
- **Better perceived performance** — The page feels faster even though actual load times remain the same

Requirements
------------

[](#requirements)

- TYPO3 CMS 12.4+ or 13.4+
- PHP 8.2+
- GD PHP extension (required; fallback processor and part of standard TYPO3 installs)
- **Imagick PHP extension (strongly recommended for production)** — GD can cause memory exhaustion with large images
- Composer dependency: `srwiez/thumbhash ^1.4`

Notes:

- You can choose the processor via `imageProcessor` (auto|imagick|gd). Explicit choices have no fallback.
- When using GD with large images, increase PHP memory\_limit to 512MB or higher

License
-------

[](#license)

GNU General Public License version 2 or later (GPL-2.0-or-later)

Credits
-------

[](#credits)

ThumbHash algorithm by [Evan Wallace](https://github.com/evanw/thumbhash)

###  Health Score

42

—

FairBetter than 90% of packages

Maintenance69

Regular maintenance activity

Popularity27

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity49

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 95% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~23 days

Total

2

Last Release

227d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/f4ea950f22b43e010ba4f0a6effb0928a6a1d11f64d36cec0d030b757bdfa85e?d=identicon)[wazum](/maintainers/wazum)

---

Top Contributors

[![wazum](https://avatars.githubusercontent.com/u/146727?v=4)](https://github.com/wazum "wazum (19 commits)")[![garvinhicking](https://avatars.githubusercontent.com/u/273326?v=4)](https://github.com/garvinhicking "garvinhicking (1 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPsalm

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/wazum-thumb-hash/health.svg)

```
[![Health](https://phpackages.com/badges/wazum-thumb-hash/health.svg)](https://phpackages.com/packages/wazum-thumb-hash)
```

###  Alternatives

[netresearch/rte-ckeditor-image

Image support in CKEditor for the TYPO3 ecosystem - by Netresearch

63991.3k4](/packages/netresearch-rte-ckeditor-image)[christophlehmann/imageoptimizer

Optimize uploaded/processed images with binaries of your choice

46501.8k](/packages/christophlehmann-imageoptimizer)[plan2net/webp

Creates WebP copies for images (TYPO3 CMS)

661.4M3](/packages/plan2net-webp)[tobimori/kirby-thumbhash

Kirby Image placeholders with the smarter ThumbHash integration

378.1k1](/packages/tobimori-kirby-thumbhash)[blueways/bw-focuspoint-images

Image Editor for adding focus points to images

12102.7k1](/packages/blueways-bw-focuspoint-images)[fab/media-upload

Fluid widget for mass uploading files on the Frontend using HTML5 techniques powered by Fine Uploader - http://fineuploader.com/

1927.8k1](/packages/fab-media-upload)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
