Skip to content

MIME Type Reference — TypeScript 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 TypeScript 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. 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. `type` always equals
// the top-level segment of the entry's own `mime`, so the category filter and
// the Content-Type never disagree.

/** The seven top-level media types a curated entry can belong to. */
export type MimeCategory =
  | 'text'
  | 'image'
  | 'audio'
  | 'video'
  | 'application'
  | 'font'
  | 'multipart';

export interface MimeEntry {
  /** File extension, lowercase, no leading dot (e.g. `json`). */
  ext: string;
  /** Full MIME / Content-Type string (e.g. `application/json`). */
  mime: string;
  /** Top-level media type - matches the `mime` string's first segment. */
  type: MimeCategory;
  /** Human-readable format name (e.g. `JSON`). */
  name: string;
}

/** Display order of the categories (used by the UI filter). */
export const MIME_CATEGORIES: MimeCategory[] = [
  '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.
 */
export const MIME: MimeEntry[] = [
  // ── 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. */
export function normalizeExt(ext: string): string {
  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.
 */
export function lookupByExt(ext: string): MimeEntry[] {
  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.
 */
export function lookupByMime(mime: string): MimeEntry[] {
  const m = mime.trim().toLowerCase();
  if (!m) return [];
  return MIME.filter((e) => e.mime.toLowerCase() === m);
}

export interface MimeFilter {
  /** Constrain to a single top-level category. Omitted = any category. */
  type?: MimeCategory;
  /** Free text matched (case-insensitively) against ext, mime, and name. */
  query?: string;
}

/**
 * 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).
 */
export function filter(opts: MimeFilter = {}): MimeEntry[] {
  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 →