Explainer: QuickLook

QuickLook, or Quick Look, is the part of macOS responsible for generating custom Thumbnails and Previews of items in the Finder and elsewhere. Although it was only introduced in 2007, with Mac OS X 10.5 Leopard, its origins go back to 1988-91 when image Thumbnails could be saved in a file’s ICN# resource. A similar system arrived in Mac OS X, and was replaced by the first version of QuickLook in 2007, which has recently undergone revision, over the period 2019-25.

Resource-based Thumbnails in Classic Mac OS were relatively straightforward. Each type of file had its own icon, an association made in the hidden Desktop database. Image and video files often overrode that default by providing their own Thumbnail image as a resource, and had to update those when the file’s data was changed. Amazingly that’s still supported in modern macOS 35 years later.

QuickLook took on the task of generating Thumbnail images, and added larger Previews in which the whole document can be inspected without opening it in an app. This came with built-in Thumbnail and Preview generation for a wide range of common document types, extending to QuickTime media including audio and video. Apps are different, though, as they use icon image (icns) files stored in their bundle’s Resources folder, harking back to Classic icon resources.

Display of Thumbnails used the QuickLook framework documented here. This enabled third-parties to extend coverage to their own document types using QuickLook generators with the extension qlgenerator. Initially, they were installed into /Library/QuickLook from each app bundle.

Unlike Spotlight indexes and document versions, QuickLook stores all its files in the current Data volume, rather than locally on individual volumes. Normally, when QuickLook generated a Thumbnail or Preview, that was stored in its cache database kept in a temporary directory in the path C/com.apple.QuickLook.thumbnailcache/. Those could give revealing insights into images and other documents accessed recently, and Wojciech Regula and Patrick Wardle discovered that, in High Sierra and earlier, it was easy for malicious software to examine that cache. Apple addressed that in macOS 10.14 Mojave by making that cache completely inaccessible.

In-memory caching of Thumbnails has also proved controversial in more recent versions of macOS. To deliver smooth scrolling of Thumbnails in the Finder’s Gallery views in particular, the Finder has taken to caching them in memory for up to two days, sometimes using several GB in the process.

I described how QuickLook Thumbnails worked in early 2019, in the days before the SSV.

getdocicon01

When you selected a document in the Finder, a dialog, or somewhere else where you expect its icon to be shown, the Finder passed details of the document path and its type (UTI) to IconServices, to fetch the appropriate icon. This called on its main service, iconservicesd in /System/Library/CoreServices, to check its icon cache.

Although the main icon store is locked away in /Library/Caches/com.apple.iconservices.store, there was additional data in a folder on a path based on /private/var/folders/…/C/com.apple.iconservices, where … is an unreadable alphanumeric name. For icons used in the Dock, their cache was at /private/var/folders/…/C/com.apple.dock.iconcache. If the icon should be replaced by a QuickLook Thumbnail, such as in a Finder column view, QuickLook is asked to provide that thumbnail. That in turn may be cached in its protected cache at /private/var/folders/…/C/com.apple.QuickLook.thumbnailcache.

QuickLook then relied on there being an appropriate qlgenerator to create a thumbnail of that document type; if the qlgenerator was flawed or could’t cope with the document’s contents, that could easily fall over. For example, if you renamed a text file with a .jpeg extension so that macOS considered it was a JPEG image, the bundled qlgenerator might have simply resulted in the display of a busy spinner, rather than resolving to a generic JPEG document icon. IconServices should then deliver the appropriate icon back to the Finder to display it.

In macOS 10.15 Catalina (2019), Apple started replacing this system with a new framework named QuickLook Thumbnailing, documented here. That replaces qlgenerators with QuickLook preview extensions, in particular Thumbnail Extensions, as explained to developers at WWDC in 2019.

macOS 15.0 Sequoia finally removed support for third-party qlgenerators, resulting in the unfortunate loss of custom Thumbnails and Previews for document types of apps that are still reliant on qlgenerators, and haven’t yet got round to providing equivalent app extensions.

When you now select a file in a view which should result in the display of its thumbnail in the Preview pane in that window, the Finder requests it from the QuickLookThumbnailingDaemon. That queues the request until the daemon can look for the image in its memory cache. If it can’t find it there it then looks in the disk cache, first at low quality 20 x 20 icon mode. If it still can’t find it, it queues a request for a fresh thumbnail to be generated. That uses the file data together with the appropriate code to create a Thumbnail, which is then returned and cached.

There’s at least one exception to this, the directory at ~/Library/Messages/Attachments/. For files inside that, and any others for which a Thumbnail can’t be generated, a generic icon is returned as the “most representative thumbnail”.

While third parties have been replacing their old qlgenerators with modern Thumbnail and Preview extensions (appexes), macOS still provides its standard qlgenerators in /System/Library/QuickLook. Third party appexes normally come in PlugIns folders in app bundles. Mints can provide a full listing of those installed. If a document type isn’t being thumbnailed as you’d expect, the first task is to discover its type as a UTI. You can then look up which qlgenerator or appex should be responsible for generating Thumbnails or Previews of that document type using Mints. By far the most common cause at present is an old third-party qlgenerator that hasn’t been replaced by an appex.