mime-types vs file-type vs mime vs mime-db vs mime-lookup
MIME Type Detection and Lookup in JavaScript Applications
mime-typesfile-typemimemime-dbmime-lookupSimilar Packages:

MIME Type Detection and Lookup in JavaScript Applications

file-type, mime, mime-db, mime-lookup, and mime-types are npm packages that help developers work with MIME types—essential identifiers for file formats and content types on the web. file-type detects MIME types by examining the first bytes of a file (magic number detection), making it ideal for verifying uploaded files. The other four packages focus on mapping between file extensions and MIME types, but differ in scope and layering: mime-db is a raw JSON database of MIME type definitions; mime-types and mime-lookup build on top of it to provide lookup utilities; and mime offers a higher-level, all-in-one API that includes both extension-to-type and type-to-extension conversion. These tools are commonly used in file upload handlers, static asset servers, and content negotiation logic.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
mime-types189,857,1871,45722.9 kB224 months agoMIT
file-type04,259135 kB08 days agoMIT
mime02,354161 kB57 months agoMIT
mime-db01,228226 kB40a year agoMIT
mime-lookup01-0-MIT

MIME Type Handling in JavaScript: file-type vs mime vs mime-db vs mime-lookup vs mime-types

When building applications that handle files—whether in a Node.js backend, a browser-based uploader, or a static site generator—you’ll often need to answer two fundamental questions:

  1. What is this file actually? (based on its content)
  2. What MIME type corresponds to this file extension? (or vice versa)

The five packages under review address these needs in different ways. Let’s break down their roles, capabilities, and trade-offs.

🔍 Detecting File Type from Content: Only file-type Does This

file-type is in a category of its own: it reads the first few bytes of a file (the “magic number”) to determine its true format. This is essential when you can’t trust the filename or user input.

// In Node.js
import { fileTypeFromBuffer } from 'file-type';
const buffer = await fs.readFile('unknown-file');
const result = await fileTypeFromBuffer(buffer);
console.log(result?.mime); // e.g., 'image/png'

// In the browser
import { fileTypeFromBlob } from 'file-type';
const blob = new Blob(['...'], { type: 'application/octet-stream' });
const result = await fileTypeFromBlob(blob);
console.log(result?.mime); // actual detected type

None of the other packages (mime, mime-db, etc.) can do this—they only work with extensions or known type strings. If your use case involves file validation or security, file-type is non-negotiable.

📚 Mapping Extensions to MIME Types: The Other Four Packages

The remaining packages help you convert between file extensions (like .css) and MIME types (like text/css). But they differ significantly in design and maintenance status.

mime: Self-Contained and Simple

mime ships with its own built-in list of common types. You don’t need to pull in external data.

import mime from 'mime';

console.log(mime.getType('txt'));      // 'text/plain'
console.log(mime.getExtension('image/png')); // 'png'

It’s fast, has zero dependencies, and works everywhere. But its dataset isn’t as comprehensive or frequently updated as the official IANA registry.

mime-db: Raw Data Only

mime-db exports a plain JSON object containing the full IANA MIME type database. It provides no functions—just data.

import db from 'mime-db';

console.log(db['image/png']); 
// { source: 'iana', extensions: ['png'] }

// You’d have to write your own lookup logic:
function lookup(ext) {
  for (const [type, info] of Object.entries(db)) {
    if (info.extensions?.includes(ext)) return type;
  }
}

This is useful only if you’re building a MIME library yourself. Application code should avoid it.

mime-lookup: Deprecated and Redundant

mime-lookup was a thin wrapper over mime-db for extension-to-type lookups:

// ⚠️ Do not use in new projects — deprecated
import lookup from 'mime-lookup';

console.log(lookup('js')); // 'application/javascript'

However, its npm page states it’s deprecated, and the GitHub repo is archived. Use mime-types instead.

mime-types: The Standard for Accurate Lookups

mime-types uses mime-db under the hood but provides a clean, well-tested API for both directions:

import * as mimeTypes from 'mime-types';

console.log(mimeTypes.lookup('style.css')); // 'text/css'
console.log(mimeTypes.extension('text/html')); // 'html'
console.log(mimeTypes.charset('text/plain')); // 'UTF-8'

It’s actively maintained, follows the official registry closely, and handles nuances like default charsets for text types—something mime doesn’t do.

🧪 Real-World Decision Guide

Scenario 1: Validating User Uploads

You’re building a profile picture uploader and must ensure users can’t upload HTML files disguised as .jpg.

  • Use file-type to inspect the file’s binary header.
  • ❌ Don’t rely on mime or mime-types—they only check the extension.
const fileType = await fileTypeFromBuffer(fileBuffer);
if (fileType?.mime !== 'image/jpeg' && fileType?.mime !== 'image/png') {
  throw new Error('Only JPEG/PNG allowed');
}

Scenario 2: Serving Static Files in a Custom Server

You’re writing a minimal HTTP server and need to set Content-Type based on file extensions.

  • Use mime-types for accuracy and charset support.
  • ⚠️ mime works if you only serve common assets and want fewer dependencies.
// With mime-types
res.setHeader('Content-Type', mimeTypes.contentType(path.extname(filename)));

// With mime
res.setHeader('Content-Type', mime.getType(filename));

Scenario 3: Building a MIME Utility Library

You’re creating a new framework and need to embed MIME logic.

  • Use mime-db directly if you want full control over parsing and caching.
  • Use mime-types if you want correctness without reinventing lookup logic.
  • ❌ Avoid mime-lookup—it’s deprecated.

⚠️ Critical Maintenance Notes

  • mime-lookup is deprecated. Its npm page says: “This package is deprecated. Use mime-types instead.” Do not use it in new code.
  • mime-db is not a utility—it’s a data source. It hasn’t changed much because it mirrors a stable standard, but that doesn’t mean it’s meant for direct app use.
  • file-type is the only option for content-based detection. No other package in this group reads file bytes.

📊 Summary Table

PackageDetects from Content?Extension → TypeType → ExtensionUses Official DB?Actively Maintained?
file-type✅ Yes❌ No❌ NoN/A✅ Yes
mime❌ No✅ Yes✅ Yes❌ Bundled subset✅ Yes
mime-db❌ No❌ (raw data)❌ (raw data)✅ Yes✅ (as data mirror)
mime-lookup❌ No✅ Yes❌ No✅ YesDeprecated
mime-types❌ No✅ Yes✅ Yes✅ Yes✅ Yes

💡 Final Recommendation

  • Need to verify what a file really is?file-type
  • Need accurate, standard-compliant extension/type mapping?mime-types
  • Want simplicity and small size over completeness?mime
  • Building a low-level tool that consumes raw MIME data?mime-db
  • Considering mime-lookup? → Don’t. It’s deprecated—use mime-types instead.

In most real-world applications, you’ll end up using file-type for uploads and mime-types for serving, covering both security and correctness needs.

How to Choose: mime-types vs file-type vs mime vs mime-db vs mime-lookup

  • mime-types:

    Choose mime-types when you need a robust, up-to-date utility for bidirectional MIME type lookups (extension ↔ type) based on the official mime-db dataset. It’s actively maintained, supports both Node.js and bundlers, and handles edge cases like charset defaults for text types. It’s ideal for web servers, file processors, or any system that must accurately interpret or generate Content-Type headers.

  • file-type:

    Choose file-type when you need to reliably determine a file's true MIME type by inspecting its binary content rather than trusting its extension or user-provided metadata. This is critical for security-sensitive contexts like file uploads, where an attacker might disguise a malicious script as an image. It works in both Node.js and modern browsers via ArrayBuffer or Blob inputs, but cannot infer types from filenames or extensions alone.

  • mime:

    Choose mime when you want a simple, self-contained utility for common tasks like converting .jpg to image/jpeg or vice versa, without managing dependencies on external databases. It bundles its own compact MIME type dataset, so it works offline and loads quickly. It’s well-suited for lightweight servers, CLI tools, or frontend apps that need basic extension/type mapping without extra overhead.

  • mime-db:

    Choose mime-db only if you're building a low-level library that requires direct access to the full, unprocessed IANA MIME type database in JSON format. It provides no helper functions—just raw data—so it’s not intended for direct application use. Most developers should instead use mime-types or mime, which consume this data and expose convenient APIs.

  • mime-lookup:

    Choose mime-lookup if you specifically need a minimal, focused package that maps file extensions to MIME types using the mime-db dataset, and you don’t require reverse lookups (type to extension). However, note that this package is deprecated as of 2023 and should be avoided in new projects; prefer mime-types or mime instead.

README for mime-types

mime-types

NPM Version NPM Downloads Node.js Version Build Status Test Coverage

The ultimate javascript content-type utility.

Similar to the mime@1.x module, except:

  • No fallbacks. Instead of naively returning the first available type, mime-types simply returns false, so do var type = mime.lookup('unrecognized') || 'application/octet-stream'.
  • No new Mime() business, so you could do var lookup = require('mime-types').lookup.
  • No .define() functionality
  • Bug fixes for .lookup(path)

Otherwise, the API is compatible with mime 1.x.

Install

This is a Node.js module available through the npm registry. Installation is done using the npm install command:

$ npm install mime-types

Note on MIME Type Data and Semver

This package considers the programmatic api as the semver compatibility. Additionally, the package which provides the MIME data for this package (mime-db) also considers it's programmatic api as the semver contract. This means the MIME type resolution is not considered in the semver bumps.

In the past the version of mime-db was pinned to give two decision points when adopting MIME data changes. This is no longer true. We still update the mime-db package here as a minor release when necessary, but will use a ^ range going forward. This means that if you want to pin your mime-db data you will need to do it in your application. While this expectation was not set in docs until now, it is how the pacakge operated, so we do not feel this is a breaking change.

If you wish to pin your mime-db version you can do that with overrides via your package manager of choice. See their documentation for how to correctly configure that.

Adding Types

All mime types are based on mime-db, so open a PR there if you'd like to add mime types.

API

var mime = require('mime-types')

All functions return false if input is invalid or not found.

mime.lookup(path)

Lookup the content-type associated with a file.

mime.lookup('json') // 'application/json'
mime.lookup('.md') // 'text/markdown'
mime.lookup('file.html') // 'text/html'
mime.lookup('folder/file.js') // 'application/javascript'
mime.lookup('folder/.htaccess') // false

mime.lookup('cats') // false

mime.contentType(type)

Create a full content-type header given a content-type or extension. When given an extension, mime.lookup is used to get the matching content-type, otherwise the given content-type is used. Then if the content-type does not already have a charset parameter, mime.charset is used to get the default charset and add to the returned content-type.

mime.contentType('markdown') // 'text/x-markdown; charset=utf-8'
mime.contentType('file.json') // 'application/json; charset=utf-8'
mime.contentType('text/html') // 'text/html; charset=utf-8'
mime.contentType('text/html; charset=iso-8859-1') // 'text/html; charset=iso-8859-1'

// from a full path
mime.contentType(path.extname('/path/to/file.json')) // 'application/json; charset=utf-8'

mime.extension(type)

Get the default extension for a content-type.

mime.extension('application/octet-stream') // 'bin'

mime.charset(type)

Lookup the implied default charset of a content-type.

mime.charset('text/markdown') // 'UTF-8'

var type = mime.types[extension]

A map of content-types by extension.

[extensions...] = mime.extensions[type]

A map of extensions by content-type.

License

MIT