MIME Type Reference — JavaScript source
A searchable map of common file extensions to their MIME types - text, image, audio, video, application, font, and multipart. Look up by extension or by type, filter by category, and copy the exact Content-Type string for any format.
This is the JavaScript implementation — the same logic the interactive tool runs, in a shareable, citable form.
/**
* MIME / Content-Type reference - pure, deterministic data + lookups. No DOM,
* no React, zero dependencies.
*
* Language: JavaScript (ES module).
* CosmoDev polyglot showcase port of the `mime-types` tool, ported from
* src/lib/mime-types.ts. Display source - part of CosmoDev's polyglot tool
* pages.
*
* A curated set of common file extensions mapped to their standard MIME types,
* grouped by the seven top-level media types (RFC 2046): text, image, audio,
* video, application, font, and multipart. Each entry's `type` always equals
* the top-level segment of its own `mime`, so the category filter and the
* Content-Type never disagree.
*/
/**
* The seven top-level media types a curated entry can belong to.
* @typedef {'text'|'image'|'audio'|'video'|'application'|'font'|'multipart'} MimeCategory
*/
/**
* One curated extension ↔ MIME mapping.
* @typedef {Object} MimeEntry
* @property {string} ext - File extension, lowercase, no leading dot (e.g. `json`).
* @property {string} mime - Full MIME / Content-Type string (e.g. `application/json`).
* @property {MimeCategory} type - Top-level media type - matches `mime`'s first segment.
* @property {string} name - Human-readable format name (e.g. `JSON`).
*/
/**
* Filter options for {@link filter}.
* @typedef {Object} MimeFilter
* @property {MimeCategory} [type] - Constrain to a single top-level category. Omitted = any.
* @property {string} [query] - Free text matched case-insensitively against ext/mime/name.
*/
/** Display order of the categories (used by the UI filter). */
export const MIME_CATEGORIES = [
'text',
'image',
'audio',
'video',
'application',
'font',
'multipart',
];
/**
* The curated extension ↔ MIME table. One entry is one (extension, type) pair,
* so a single extension with several MIME types (e.g. `.js`) appears more than
* once, and a single MIME with several extensions (e.g. `image/jpeg`) appears
* once per extension. MIME values follow IANA / MDN conventions.
*
* @type {MimeEntry[]}
*/
export const MIME = [
// ── text ────────────────────────────────────────────────────────────────
{ ext: 'txt', mime: 'text/plain', type: 'text', name: 'Plain text' },
{ ext: 'html', mime: 'text/html', type: 'text', name: 'HTML document' },
{ ext: 'htm', mime: 'text/html', type: 'text', name: 'HTML document' },
{ ext: 'xhtml', mime: 'application/xhtml+xml', type: 'application', name: 'XHTML' },
{ ext: 'css', mime: 'text/css', type: 'text', name: 'CSS stylesheet' },
{ ext: 'csv', mime: 'text/csv', type: 'text', name: 'Comma-separated values' },
{ ext: 'xml', mime: 'application/xml', type: 'application', name: 'XML document' },
{ ext: 'js', mime: 'text/javascript', type: 'text', name: 'JavaScript' },
{ ext: 'js', mime: 'application/javascript', type: 'application', name: 'JavaScript (legacy)' },
{ ext: 'mjs', mime: 'text/javascript', type: 'text', name: 'JavaScript module' },
{ ext: 'json', mime: 'application/json', type: 'application', name: 'JSON' },
{ ext: 'md', mime: 'text/markdown', type: 'text', name: 'Markdown' },
{ ext: 'yaml', mime: 'text/yaml', type: 'text', name: 'YAML' },
{ ext: 'yml', mime: 'text/yaml', type: 'text', name: 'YAML' },
{ ext: 'ics', mime: 'text/calendar', type: 'text', name: 'iCalendar' },
{ ext: 'rtf', mime: 'application/rtf', type: 'application', name: 'Rich text' },
{ ext: 'tsv', mime: 'text/tab-separated-values', type: 'text', name: 'Tab-separated values' },
// ── image ───────────────────────────────────────────────────────────────
{ ext: 'jpg', mime: 'image/jpeg', type: 'image', name: 'JPEG image' },
{ ext: 'jpeg', mime: 'image/jpeg', type: 'image', name: 'JPEG image' },
{ ext: 'png', mime: 'image/png', type: 'image', name: 'PNG image' },
{ ext: 'gif', mime: 'image/gif', type: 'image', name: 'GIF image' },
{ ext: 'webp', mime: 'image/webp', type: 'image', name: 'WebP image' },
{ ext: 'avif', mime: 'image/avif', type: 'image', name: 'AVIF image' },
{ ext: 'svg', mime: 'image/svg+xml', type: 'image', name: 'SVG image' },
{ ext: 'bmp', mime: 'image/bmp', type: 'image', name: 'Bitmap image' },
{ ext: 'ico', mime: 'image/x-icon', type: 'image', name: 'Icon' },
{ ext: 'tif', mime: 'image/tiff', type: 'image', name: 'TIFF image' },
{ ext: 'tiff', mime: 'image/tiff', type: 'image', name: 'TIFF image' },
{ ext: 'heic', mime: 'image/heic', type: 'image', name: 'HEIC image' },
// ── audio ───────────────────────────────────────────────────────────────
{ ext: 'mp3', mime: 'audio/mpeg', type: 'audio', name: 'MP3 audio' },
{ ext: 'wav', mime: 'audio/wav', type: 'audio', name: 'WAV audio' },
{ ext: 'ogg', mime: 'audio/ogg', type: 'audio', name: 'Ogg audio' },
{ ext: 'oga', mime: 'audio/ogg', type: 'audio', name: 'Ogg audio' },
{ ext: 'flac', mime: 'audio/flac', type: 'audio', name: 'FLAC audio' },
{ ext: 'aac', mime: 'audio/aac', type: 'audio', name: 'AAC audio' },
{ ext: 'm4a', mime: 'audio/mp4', type: 'audio', name: 'M4A audio' },
{ ext: 'weba', mime: 'audio/webm', type: 'audio', name: 'WebM audio' },
{ ext: 'mid', mime: 'audio/midi', type: 'audio', name: 'MIDI' },
{ ext: 'midi', mime: 'audio/midi', type: 'audio', name: 'MIDI' },
// ── video ───────────────────────────────────────────────────────────────
{ ext: 'mp4', mime: 'video/mp4', type: 'video', name: 'MP4 video' },
{ ext: 'webm', mime: 'video/webm', type: 'video', name: 'WebM video' },
{ ext: 'avi', mime: 'video/x-msvideo', type: 'video', name: 'AVI video' },
{ ext: 'mov', mime: 'video/quicktime', type: 'video', name: 'QuickTime video' },
{ ext: 'mkv', mime: 'video/x-matroska', type: 'video', name: 'Matroska video' },
{ ext: 'mpeg', mime: 'video/mpeg', type: 'video', name: 'MPEG video' },
{ ext: 'mpg', mime: 'video/mpeg', type: 'video', name: 'MPEG video' },
{ ext: 'ogv', mime: 'video/ogg', type: 'video', name: 'Ogg video' },
{ ext: 'm4v', mime: 'video/mp4', type: 'video', name: 'M4V video' },
// ── application ─────────────────────────────────────────────────────────
{ ext: 'pdf', mime: 'application/pdf', type: 'application', name: 'PDF document' },
{ ext: 'zip', mime: 'application/zip', type: 'application', name: 'ZIP archive' },
{ ext: 'gz', mime: 'application/gzip', type: 'application', name: 'Gzip archive' },
{ ext: 'tar', mime: 'application/x-tar', type: 'application', name: 'Tar archive' },
{ ext: 'rar', mime: 'application/vnd.rar', type: 'application', name: 'RAR archive' },
{ ext: '7z', mime: 'application/x-7z-compressed', type: 'application', name: '7-Zip archive' },
{ ext: 'bin', mime: 'application/octet-stream', type: 'application', name: 'Binary data' },
{ ext: 'exe', mime: 'application/x-msdownload', type: 'application', name: 'Windows executable' },
{ ext: 'jar', mime: 'application/java-archive', type: 'application', name: 'Java archive' },
{ ext: 'wasm', mime: 'application/wasm', type: 'application', name: 'WebAssembly' },
{ ext: 'doc', mime: 'application/msword', type: 'application', name: 'Word document' },
{ ext: 'docx', mime: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', type: 'application', name: 'Word document (OOXML)' },
{ ext: 'xls', mime: 'application/vnd.ms-excel', type: 'application', name: 'Excel spreadsheet' },
{ ext: 'xlsx', mime: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', type: 'application', name: 'Excel spreadsheet (OOXML)' },
{ ext: 'ppt', mime: 'application/vnd.ms-powerpoint', type: 'application', name: 'PowerPoint' },
{ ext: 'pptx', mime: 'application/vnd.openxmlformats-officedocument.presentationml.presentation', type: 'application', name: 'PowerPoint (OOXML)' },
// ── font ────────────────────────────────────────────────────────────────
{ ext: 'woff', mime: 'font/woff', type: 'font', name: 'WOFF font' },
{ ext: 'woff2', mime: 'font/woff2', type: 'font', name: 'WOFF2 font' },
{ ext: 'ttf', mime: 'font/ttf', type: 'font', name: 'TrueType font' },
{ ext: 'otf', mime: 'font/otf', type: 'font', name: 'OpenType font' },
{ ext: 'eot', mime: 'application/vnd.ms-fontobject', type: 'application', name: 'Embedded OpenType' },
// ── multipart ───────────────────────────────────────────────────────────
{ ext: 'mht', mime: 'multipart/related', type: 'multipart', name: 'MHTML web archive' },
{ ext: 'mhtml', mime: 'multipart/related', type: 'multipart', name: 'MHTML web archive' },
];
/**
* Lowercase an extension and drop a leading dot so `.JSON` and `json` match.
*
* @param {string} ext - Raw extension from the user.
* @returns {string} Normalized extension (no whitespace, no leading dot, lowercase).
*/
export function normalizeExt(ext) {
return ext.trim().toLowerCase().replace(/^\.+/, '');
}
/**
* Find every entry whose extension matches. The dot is optional and matching is
* case-insensitive, so `lookupByExt('.js')`, `lookupByExt('JS')`, and
* `lookupByExt('js')` are equivalent. Returns `[]` for an unknown/empty ext.
*
* @param {string} ext - Extension to look up (dot optional, case-insensitive).
* @returns {MimeEntry[]}
*/
export function lookupByExt(ext) {
const e = normalizeExt(ext);
if (!e) return [];
return MIME.filter((m) => m.ext === e);
}
/**
* Find every entry whose MIME type matches, case-insensitively (also tolerating
* surrounding whitespace). One MIME commonly maps to several extensions - e.g.
* `image/jpeg` → `jpg`, `jpeg` - so all are returned. `[]` for unknown/empty.
*
* @param {string} mime - MIME / Content-Type to look up.
* @returns {MimeEntry[]}
*/
export function lookupByMime(mime) {
const m = mime.trim().toLowerCase();
if (!m) return [];
return MIME.filter((e) => e.mime.toLowerCase() === m);
}
/**
* Filter the full table by category and/or a free-text query. Omitted options
* are ignored; an empty query returns the category-filtered set unchanged. An
* unknown category value yields nothing (it is not silently coerced).
*
* @param {MimeFilter} [opts={}] - Optional `{ type?, query? }` constraints.
* @returns {MimeEntry[]}
*/
export function filter(opts = {}) {
const q = (opts.query ?? '').trim().toLowerCase();
return MIME.filter((e) => {
if (opts.type !== undefined && e.type !== opts.type) return false;
if (q) {
return (
e.ext.toLowerCase().includes(q) ||
e.mime.toLowerCase().includes(q) ||
e.name.toLowerCase().includes(q)
);
}
return true;
});
}
Also available in 13 other languages
Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →