file-type、mime、mime-db、mime-lookup、mime-types は、Web アプリケーションでファイルや MIME タイプを扱うための代表的な npm パッケージです。file-type はファイルのバイナリヘッダーを解析して実際のファイル形式を特定します。一方、mime、mime-db、mime-lookup、mime-types は MIME タイプ(例: image/png)とファイル拡張子(例: .png)の相互変換や参照を目的としており、主に HTTP の Content-Type 処理やファイルアップロード時のメタデータ生成に使われます。これらのパッケージは目的が明確に分かれており、ファイルの中身を調べたいのか、それとも既知の拡張子から MIME を引くだけなのかで選択が変わります。
ファイルを扱う Web アプリケーションでは、2種類の「タイプ」判定が必要になります。
.txt という名前だが実際は JPEG).png → image/png)前者には file-type、後者には mime / mime-types / mime-lookup が使われ、mime-db はその基盤データを提供します。それぞれの役割と使いどころを、実際のコードで見ていきましょう。
file-typefile-type は、ファイルの先頭数バイト(マジックナンバー)を読み取って、拡張子に依存せずに実際のフォーマットを判定します。これは、ユーザーが .jpg という名前で実行ファイルを送ろうとしても検出できるため、セキュリティ上非常に重要です。
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 タイプを変換するためのパッケージを見ていきます。これらはファイルの中身を一切見ず、あくまで「.pdf なら application/pdf」といったルールベースの変換を行います。
mime: オールインワンのシンプルAPImime は最も直感的な 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 してデータを取得しています。
.jpg でも、実際が PNG かどうかを確認し、悪意あるファイルを弾きたいfile-type// ファイルの実体を検証
const type = await fileTypeFromBuffer(buffer);
if (!['image/jpeg', 'image/png'].includes(type?.mime)) {
throw new Error('画像以外は禁止');
}
/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');
// ...
});
.svg → image/svg+xml の変換だけが必要で、逆変換は不要mime-lookup// 極小バンドル
const mimeType = lookup('icon.svg'); // 'image/svg+xml'
mime-db + カスタム処理(ただし、通常は mime の拡張機能を使う方が簡単)// mime パッケージの拡張機能例
mime.define({ 'application/custom': ['cust'] });
mime.getType('file.cust'); // 'application/custom'
| パッケージ | 拡張子 → MIME | MIME → 拡張子 | ファイル実体検出 | 直接使用推奨 | 主な用途 |
|---|---|---|---|---|---|
file-type | ❌ | ❌ | ✅ | ✅ | セキュアなファイル検証 |
mime | ✅ | ✅ | ❌ | ✅ | 一般的な MIME 変換 |
mime-db | ❌ (生データ) | ❌ (生データ) | ❌ | ❌ | 他のライブラリの基盤 |
mime-lookup | ✅ | ❌ | ❌ | △ | 単方向変換のみ必要なケース |
mime-types | ✅ | ✅ | ❌ | ✅ | 型安全・モジュール設計を好む場合 |
file-type を使って実体を検証してください。拡張子ベースの判定だけでは危険です。mime か mime-types を選びましょう。違いは API スタイルと TypeScript サポート程度なので、チームの好みで決めて問題ありません。mime-lookup は本当に「拡張子 → MIME」だけが必要なとき以外は避けて、mime を使う方が将来の拡張性に優れます。mime-db はアプリケーションコードで直接 import する必要はほぼありません — これは「部品」であり、「完成品」ではないからです。これらのパッケージは目的が明確に分かれているため、自分の要件に合ったものだけを選び、過剰な依存を避けることが重要です。
mime-types は、mime と同様に MIME タイプと拡張子の相互変換を提供しますが、API 設計がよりモジュール的です(例: mimeTypes.lookup('.png')、mimeTypes.extension('image/png'))。mime-db を直接利用しており、最新の MIME データを確実に反映できます。TypeScript サポートも充実しており、大規模プロジェクトや型安全性を重視する環境に向いています。
file-type は、ユーザーがアップロードしたファイルの実際の形式を信頼できる方法で判別したい場合に最適です。拡張子を信用せず、ファイルの先頭バイト(マジックナンバー)を直接読み取って判定するため、セキュリティ上重要な用途(例: 画像アップローダーでの悪意あるファイル検出)に適しています。ただし、Node.js の Buffer や Web API の Blob/ArrayBuffer を必要とするため、純粋なフロントエンド環境では使用に制限があります。
mime は、シンプルかつ軽量な MIME タイプ ↔ 拡張子の相互変換を求める場合に最適です。1つのパッケージで両方向の変換が可能で、API も直感的です(例: mime.getType('.png')、mime.getExtension('image/png'))。多くのプロジェクトで広く使われており、安定性と使いやすさを重視するなら第一候補です。
mime-db は、MIME タイプに関する生のデータベースそのものです。このパッケージ単体では変換関数は提供せず、他の MIME 関連ライブラリ(例: mime-types)が内部で利用する JSON データを提供します。通常、アプリケーションコードで直接使うことはなく、低レベルの MIME データをカスタム処理で参照したい場合にのみ考慮すべきです。
mime-lookup は、拡張子から MIME タイプを取得するだけの極めてシンプルなユーティリティです。逆変換(MIME → 拡張子)はサポートしておらず、機能が限定されています。もし「拡張子 → MIME」の変換しか不要で、依存を最小限に抑えたい場合に有効ですが、多くのケースでは mime や mime-types の方が柔軟です。
The ultimate javascript content-type utility.
Similar to the mime@1.x module, except:
mime-types simply returns false, so do
var type = mime.lookup('unrecognized') || 'application/octet-stream'.new Mime() business, so you could do var lookup = require('mime-types').lookup..define() functionality.lookup(path)Otherwise, the API is compatible with mime 1.x.
This is a Node.js module available through the
npm registry. Installation is done using the
npm install command:
$ npm install mime-types
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.
All mime types are based on mime-db, so open a PR there if you'd like to add mime types.
var mime = require('mime-types')
All functions return false if input is invalid or not found.
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
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'
Get the default extension for a content-type.
mime.extension('application/octet-stream') // 'bin'
Lookup the implied default charset of a content-type.
mime.charset('text/markdown') // 'UTF-8'
A map of content-types by extension.
A map of extensions by content-type.