mime-types vs file-type vs mime vs mime-db vs mime-lookup
ファイルタイプ検出と MIME タイプ管理のための npm パッケージ比較
mime-typesfile-typemimemime-dbmime-lookup類似パッケージ:

ファイルタイプ検出と MIME タイプ管理のための npm パッケージ比較

file-typemimemime-dbmime-lookupmime-types は、Web アプリケーションでファイルや MIME タイプを扱うための代表的な npm パッケージです。file-type はファイルのバイナリヘッダーを解析して実際のファイル形式を特定します。一方、mimemime-dbmime-lookupmime-types は MIME タイプ(例: image/png)とファイル拡張子(例: .png)の相互変換や参照を目的としており、主に HTTP の Content-Type 処理やファイルアップロード時のメタデータ生成に使われます。これらのパッケージは目的が明確に分かれており、ファイルの中身を調べたいのか、それとも既知の拡張子から MIME を引くだけなのかで選択が変わります。

npmのダウンロードトレンド

3 年

GitHub Starsランキング

統計詳細

パッケージ
ダウンロード数
Stars
サイズ
Issues
公開日時
ライセンス
mime-types152,462,3561,44822.9 kB223ヶ月前MIT
file-type33,787,4214,227110 kB32ヶ月前MIT
mime02,347161 kB05ヶ月前MIT
mime-db01,220226 kB381年前MIT
mime-lookup01-0-MIT

ファイルタイプ検出 vs MIME タイプ変換:5つの npm パッケージを深掘り

ファイルを扱う Web アプリケーションでは、2種類の「タイプ」判定が必要になります。

  1. ファイルの中身から実際の形式を特定する(例: .txt という名前だが実際は JPEG)
  2. 既知の拡張子や MIME タイプを相互に変換する(例: .pngimage/png

前者には file-type、後者には mime / mime-types / mime-lookup が使われ、mime-db はその基盤データを提供します。それぞれの役割と使いどころを、実際のコードで見ていきましょう。

🔍 ファイルの中身を調べる:file-type

file-type は、ファイルの先頭数バイト(マジックナンバー)を読み取って、拡張子に依存せずに実際のフォーマットを判定します。これは、ユーザーが .jpg という名前で実行ファイルを送ろうとしても検出できるため、セキュリティ上非常に重要です。

Node.js 環境での使用例

import { fileTypeFromBuffer } from 'file-type';
import { readFile } from 'fs/promises';

const buffer = await readFile('unknown-file');
const type = await fileTypeFromBuffer(buffer);

if (type?.mime === 'image/jpeg') {
  console.log('安全な JPEG ファイルです');
} else {
  throw new Error('許可されていないファイル形式');
}

ブラウザ環境での使用例

import { fileTypeFromBlob } from 'file-type';

const handleFile = async (file) => {
  const type = await fileTypeFromBlob(file);
  if (type?.ext === 'png') {
    // 安全に PNG として処理
  }
};

// <input type="file" onchange="handleFile(this.files[0])">

⚠️ 注意: file-type はファイルの一部(通常は最初の 4KB 以内)を読み取る必要があります。完全なファイル読み込みを避けるため、ストリーム対応も可能ですが、フロントエンドでは Blob 対応が主となります。

📄 拡張子と MIME タイプの相互変換

ここからは、既知の拡張子や MIME タイプを変換するためのパッケージを見ていきます。これらはファイルの中身を一切見ず、あくまで「.pdf なら application/pdf」といったルールベースの変換を行います。

mime: オールインワンのシンプルAPI

mime は最も直感的な API を提供します。1つのパッケージで双方向変換が可能です。

import mime from 'mime';

// 拡張子 → MIME
console.log(mime.getType('file.txt')); // 'text/plain'

// MIME → 拡張子
console.log(mime.getExtension('image/png')); // 'png'

// 存在しない場合は null
console.log(mime.getType('unknown.xyz')); // null

mime-types: モジュール設計で型安全

mime-types は、機能は mime とほぼ同じですが、関数が独立しており、TypeScript との相性が良いです。

import * as mimeTypes from 'mime-types';

// 拡張子 → MIME
console.log(mimeTypes.lookup('file.txt')); // 'text/plain'

// MIME → 拡張子
console.log(mimeTypes.extension('image/png')); // 'png'

// デフォルト値を指定可能
console.log(mimeTypes.lookup('unknown.xyz', 'application/octet-stream'));

mime-lookup: 極小の単方向変換

mime-lookup は、拡張子 → MIME の変換のみを提供する超軽量パッケージです。

import lookup from 'mime-lookup';

console.log(lookup('file.txt')); // 'text/plain'
// MIME → 拡張子はできません

もし双方向変換が必要なら、このパッケージだけでは不十分です。

mime-db: 生のデータベース(直接使うことは稀)

mime-db は、JSON 形式の MIME タイプ定義の集合体です。アプリケーションコードで直接使うことはほとんどありません。

import db from 'mime-db';

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

// 通常は、他のライブラリが内部でこれを使う

実際、mime-types は内部で mime-db を import してデータを取得しています。

🧪 実用シナリオ別:どのパッケージを選ぶべきか?

シナリオ1: ユーザーからの画像アップロード(セキュリティ重視)

  • 要件: 拡張子が .jpg でも、実際が PNG かどうかを確認し、悪意あるファイルを弾きたい
  • 選択: file-type
// ファイルの実体を検証
const type = await fileTypeFromBuffer(buffer);
if (!['image/jpeg', 'image/png'].includes(type?.mime)) {
  throw new Error('画像以外は禁止');
}

シナリオ2: API レスポンスの Content-Type 設定

  • 要件: /download/report.pdf のような URL から、Content-Type: application/pdf を自動設定したい
  • 選択: mime または mime-types
// Express 例
app.get('/download/:filename', (req, res) => {
  const mimeType = mime.getType(req.params.filename);
  res.setHeader('Content-Type', mimeType || 'application/octet-stream');
  // ...
});

シナリオ3: 最小限のバンドルサイズを追求する静的サイト

  • 要件: .svgimage/svg+xml の変換だけが必要で、逆変換は不要
  • 選択: mime-lookup
// 極小バンドル
const mimeType = lookup('icon.svg'); // 'image/svg+xml'

シナリオ4: カスタム MIME データを動的に参照したい

  • 要件: IANA 以外の独自 MIME タイプを追加・参照したい
  • 選択: mime-db + カスタム処理(ただし、通常は mime の拡張機能を使う方が簡単)
// mime パッケージの拡張機能例
mime.define({ 'application/custom': ['cust'] });
mime.getType('file.cust'); // 'application/custom'

📊 機能比較表

パッケージ拡張子 → MIMEMIME → 拡張子ファイル実体検出直接使用推奨主な用途
file-typeセキュアなファイル検証
mime一般的な MIME 変換
mime-db❌ (生データ)❌ (生データ)他のライブラリの基盤
mime-lookup単方向変換のみ必要なケース
mime-types型安全・モジュール設計を好む場合

💡 最終的なアドバイス

  • ファイルの中身を信用できない環境(例: ユーザーアップロード)では、必ず file-type を使って実体を検証してください。拡張子ベースの判定だけでは危険です。
  • 一般的な MIME 変換には、mimemime-types を選びましょう。違いは API スタイルと TypeScript サポート程度なので、チームの好みで決めて問題ありません。
  • mime-lookup は本当に「拡張子 → MIME」だけが必要なとき以外は避けて、mime を使う方が将来の拡張性に優れます。
  • mime-db はアプリケーションコードで直接 import する必要はほぼありません — これは「部品」であり、「完成品」ではないからです。

これらのパッケージは目的が明確に分かれているため、自分の要件に合ったものだけを選び、過剰な依存を避けることが重要です。

選び方: mime-types vs file-type vs mime vs mime-db vs mime-lookup

  • mime-types:

    mime-types は、mime と同様に MIME タイプと拡張子の相互変換を提供しますが、API 設計がよりモジュール的です(例: mimeTypes.lookup('.png')mimeTypes.extension('image/png'))。mime-db を直接利用しており、最新の MIME データを確実に反映できます。TypeScript サポートも充実しており、大規模プロジェクトや型安全性を重視する環境に向いています。

  • file-type:

    file-type は、ユーザーがアップロードしたファイルの実際の形式を信頼できる方法で判別したい場合に最適です。拡張子を信用せず、ファイルの先頭バイト(マジックナンバー)を直接読み取って判定するため、セキュリティ上重要な用途(例: 画像アップローダーでの悪意あるファイル検出)に適しています。ただし、Node.js の Buffer や Web API の Blob/ArrayBuffer を必要とするため、純粋なフロントエンド環境では使用に制限があります。

  • mime:

    mime は、シンプルかつ軽量な MIME タイプ ↔ 拡張子の相互変換を求める場合に最適です。1つのパッケージで両方向の変換が可能で、API も直感的です(例: mime.getType('.png')mime.getExtension('image/png'))。多くのプロジェクトで広く使われており、安定性と使いやすさを重視するなら第一候補です。

  • mime-db:

    mime-db は、MIME タイプに関する生のデータベースそのものです。このパッケージ単体では変換関数は提供せず、他の MIME 関連ライブラリ(例: mime-types)が内部で利用する JSON データを提供します。通常、アプリケーションコードで直接使うことはなく、低レベルの MIME データをカスタム処理で参照したい場合にのみ考慮すべきです。

  • mime-lookup:

    mime-lookup は、拡張子から MIME タイプを取得するだけの極めてシンプルなユーティリティです。逆変換(MIME → 拡張子)はサポートしておらず、機能が限定されています。もし「拡張子 → MIME」の変換しか不要で、依存を最小限に抑えたい場合に有効ですが、多くのケースでは mimemime-types の方が柔軟です。

mime-types のREADME

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