How does macOS tell the type of a file?

The most distinctive and revolutionary feature of the Mac is the Finder, and one of its fundamental skills is to know what type each file is. This enables it to open that file with your preferred app, to preview its contents using QuickLook, and to index its contents for Spotlight search. Those and many other features we take for granted depend on every file having a type, a designator to associate that file with a file format and apps that can open it.

UTI

The standard system in macOS is based on a Uniform Type Indicator, or UTI, like public.plain-text for a plain text file, and public.jpeg for a JPEG image.

UTIs use a structured hierarchical taxonomy forming a vast interconnected tree. For example, when I write a file of Swift source code, the .swift file has the type public.swift-source, which is a specialised type of public.source-code, which is both public.data and public.plain-text, which is public.text. When I open that file, LaunchServices first looks for an editor for public.swift-source files, but can ascend the UTI tree as necessary and use an app designed to open text files of public.text more generally. Some of the more frequently encountered UTIs are shown in the diagram below, which you’ll probably need to expand to full screen to read clearly.

UTIs

Determining the UTI

It’s often claimed that macOS depends on filename extensions to determine different types of file, but that’s incorrect: macOS is more capable, and uses MIME types when downloading from the Internet, can still use old Classic Mac OS four-character type codes, and ultimately relies on UTIs.

This is easily demonstrated in Terminal. Type the following command
touch notypefile
to create a new file in the current directory without any extension or other clue as to what it is. Then look in the Finder’s Get Info dialog, and you should see that macOS has already assigned it a default type associating it with a default editor. Inspect that file using my free utility Precize, and you’ll see that it has a UTI (listed in the Type entry) of public.data.

Now give it an extension unknown to macOS, such as .xyz, and inspect it again with Precize: its type has changed to something more cryptic like dyn.ah62d4rv4ge81u8p4. That’s a dynamic UTI, created on the fly by macOS to distinguish it as having a unique type, described in Get Info simply as a Document, but still with its default associated editor.

Every item in your Mac’s file system has a UTI to tell Launch Services what to do when you try to open it, for instance by double-clicking its icon. You may find an exception to this, from a longstanding bug dating back to OS X 10.5 in 2007: some files may not return a UTI, but a NULL instead. This seems to be confined to sockets, which might appear to be files but aren’t really.

Discovering the UTI

Unfortunately, although discovering UTIs is key to dealing with documents which are treated as having the wrong type, there’s no easy way to find a file’s UTI in macOS. Thankfully you don’t need long reference lists to find out key information such as what a filename extension or MIME type represents in terms of a UTI: it’s all contained within macOS, if you know how to look using one of the tools listed below.

My own utility for working with UTIs is UTIutility, which I have just updated to version 1.2, with improvements in its crawler to scan folders and list the UTIs it discovers there. It’s now available from here: utiutil12
from Downloads above, and from its Product Page.

utilutil121

UTIutility’s main window lets you enter an extension like xls, and tells you all macOS knows about that and its corresponding UTI. Alternatively, you can open its Crawler window and get it to list all the UTIs it comes across in the selected folder. That can take a long time to work through large folders, or those loaded with UTIs like /Applications, but its results are revealing.

utilutil122

The correct answer to the question of what determines a file’s type is therefore a whole list:

  • UTI, e.g. com.adobe.pdf,
  • filename extension, e.g pdf,
  • OSType, e.g. PDF,
  • MIME type, e.g. application/pdf, or
  • Pasteboard type, e.g. Apple PDF pasteboard type.

While you can change a file’s type directly by giving it a different UTI, it’s far simpler to do that indirectly by changing its extension to one correct for the type, such as txt or text for a text file. The OSType refers back to Classic Mac OS, as it’s the four-character type system used before UTIs. MIME types are mainly used for Internet file transfers, and Pasteboards are used when copying chunks of data using the Clipboard, which relies on the same basic system.

LaunchServices

UTIs are one of the many pieces of information stored by LaunchServices in its registry. If you’ve got a few spare MB of disk space and want to see what it gathers, you dump that to a text file using a command like
/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -dump -all system > lsdump.txt
Further information about the hidden lsregistry command is here, and Thomas Tempelmann’s utility is invaluable.

Tools

Thomas Tempelmann’s free Launch Services features an excellent UTI browser.
Precize and UTIutility are free from their Product Page.

Apple documentation

UTI overview (archived)
Framework doc (current)
System-declared UTIs (current).