Skip to content

MIME Type Reference — C# 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 C# implementation — the same logic the interactive tool runs, in a shareable, citable form.

// mime-types — C# port of the curated extension ↔ MIME table, ported from
// src/lib/mime-types.ts. Display source for CosmoDev's polyglot tool pages.
//
// The table is an immutable list of 71 entries grouped by the seven top-level
// media types (RFC 2046). Each entry's Type always equals the top-level
// segment of its own Mime, so the category filter and the Content-Type never
// disagree.

using System;
using System.Collections.Generic;
using System.Linq;

namespace MimeTypes;

/// <summary>The seven top-level media types a curated entry can belong to.</summary>
public enum MimeCategory
{
    Text,
    Image,
    Audio,
    Video,
    Application,
    Font,
    Multipart,
}

/// <summary>One curated extension ↔ MIME mapping (immutable value object).</summary>
/// <param name="Ext">File extension, lowercase, no leading dot (e.g. "json").</param>
/// <param name="Mime">Full MIME / Content-Type string (e.g. "application/json").</param>
/// <param name="Type">Top-level media type — matches the Mime string's first segment.</param>
/// <param name="Name">Human-readable format name (e.g. "JSON").</param>
public readonly record struct MimeEntry(string Ext, string Mime, MimeCategory Type, string Name);

public static class MimeTable
{
    /// <summary>Display order of the categories (used by the UI filter).</summary>
    public static readonly IReadOnlyList<MimeCategory> MimeCategories = new[]
    {
        MimeCategory.Text, MimeCategory.Image, MimeCategory.Audio, MimeCategory.Video,
        MimeCategory.Application, MimeCategory.Font, MimeCategory.Multipart,
    };

    /// <summary>
    /// The curated extension ↔ MIME table. One entry is one (extension, type)
    /// pair, so an extension with several MIME types (e.g. .js) appears more
    /// than once, and a MIME with several extensions (e.g. image/jpeg)
    /// appears once per extension. Values follow IANA / MDN conventions.
    /// </summary>
    private static readonly IReadOnlyList<MimeEntry> Mime = new[]
    {
        // ── text ────────────────────────────────────────────────────────
        new MimeEntry("txt", "text/plain", MimeCategory.Text, "Plain text"),
        new MimeEntry("html", "text/html", MimeCategory.Text, "HTML document"),
        new MimeEntry("htm", "text/html", MimeCategory.Text, "HTML document"),
        new MimeEntry("xhtml", "application/xhtml+xml", MimeCategory.Application, "XHTML"),
        new MimeEntry("css", "text/css", MimeCategory.Text, "CSS stylesheet"),
        new MimeEntry("csv", "text/csv", MimeCategory.Text, "Comma-separated values"),
        new MimeEntry("xml", "application/xml", MimeCategory.Application, "XML document"),
        new MimeEntry("js", "text/javascript", MimeCategory.Text, "JavaScript"),
        new MimeEntry("js", "application/javascript", MimeCategory.Application, "JavaScript (legacy)"),
        new MimeEntry("mjs", "text/javascript", MimeCategory.Text, "JavaScript module"),
        new MimeEntry("json", "application/json", MimeCategory.Application, "JSON"),
        new MimeEntry("md", "text/markdown", MimeCategory.Text, "Markdown"),
        new MimeEntry("yaml", "text/yaml", MimeCategory.Text, "YAML"),
        new MimeEntry("yml", "text/yaml", MimeCategory.Text, "YAML"),
        new MimeEntry("ics", "text/calendar", MimeCategory.Text, "iCalendar"),
        new MimeEntry("rtf", "application/rtf", MimeCategory.Application, "Rich text"),
        new MimeEntry("tsv", "text/tab-separated-values", MimeCategory.Text, "Tab-separated values"),

        // ── image ───────────────────────────────────────────────────────
        new MimeEntry("jpg", "image/jpeg", MimeCategory.Image, "JPEG image"),
        new MimeEntry("jpeg", "image/jpeg", MimeCategory.Image, "JPEG image"),
        new MimeEntry("png", "image/png", MimeCategory.Image, "PNG image"),
        new MimeEntry("gif", "image/gif", MimeCategory.Image, "GIF image"),
        new MimeEntry("webp", "image/webp", MimeCategory.Image, "WebP image"),
        new MimeEntry("avif", "image/avif", MimeCategory.Image, "AVIF image"),
        new MimeEntry("svg", "image/svg+xml", MimeCategory.Image, "SVG image"),
        new MimeEntry("bmp", "image/bmp", MimeCategory.Image, "Bitmap image"),
        new MimeEntry("ico", "image/x-icon", MimeCategory.Image, "Icon"),
        new MimeEntry("tif", "image/tiff", MimeCategory.Image, "TIFF image"),
        new MimeEntry("tiff", "image/tiff", MimeCategory.Image, "TIFF image"),
        new MimeEntry("heic", "image/heic", MimeCategory.Image, "HEIC image"),

        // ── audio ───────────────────────────────────────────────────────
        new MimeEntry("mp3", "audio/mpeg", MimeCategory.Audio, "MP3 audio"),
        new MimeEntry("wav", "audio/wav", MimeCategory.Audio, "WAV audio"),
        new MimeEntry("ogg", "audio/ogg", MimeCategory.Audio, "Ogg audio"),
        new MimeEntry("oga", "audio/ogg", MimeCategory.Audio, "Ogg audio"),
        new MimeEntry("flac", "audio/flac", MimeCategory.Audio, "FLAC audio"),
        new MimeEntry("aac", "audio/aac", MimeCategory.Audio, "AAC audio"),
        new MimeEntry("m4a", "audio/mp4", MimeCategory.Audio, "M4A audio"),
        new MimeEntry("weba", "audio/webm", MimeCategory.Audio, "WebM audio"),
        new MimeEntry("mid", "audio/midi", MimeCategory.Audio, "MIDI"),
        new MimeEntry("midi", "audio/midi", MimeCategory.Audio, "MIDI"),

        // ── video ───────────────────────────────────────────────────────
        new MimeEntry("mp4", "video/mp4", MimeCategory.Video, "MP4 video"),
        new MimeEntry("webm", "video/webm", MimeCategory.Video, "WebM video"),
        new MimeEntry("avi", "video/x-msvideo", MimeCategory.Video, "AVI video"),
        new MimeEntry("mov", "video/quicktime", MimeCategory.Video, "QuickTime video"),
        new MimeEntry("mkv", "video/x-matroska", MimeCategory.Video, "Matroska video"),
        new MimeEntry("mpeg", "video/mpeg", MimeCategory.Video, "MPEG video"),
        new MimeEntry("mpg", "video/mpeg", MimeCategory.Video, "MPEG video"),
        new MimeEntry("ogv", "video/ogg", MimeCategory.Video, "Ogg video"),
        new MimeEntry("m4v", "video/mp4", MimeCategory.Video, "M4V video"),

        // ── application ─────────────────────────────────────────────────
        new MimeEntry("pdf", "application/pdf", MimeCategory.Application, "PDF document"),
        new MimeEntry("zip", "application/zip", MimeCategory.Application, "ZIP archive"),
        new MimeEntry("gz", "application/gzip", MimeCategory.Application, "Gzip archive"),
        new MimeEntry("tar", "application/x-tar", MimeCategory.Application, "Tar archive"),
        new MimeEntry("rar", "application/vnd.rar", MimeCategory.Application, "RAR archive"),
        new MimeEntry("7z", "application/x-7z-compressed", MimeCategory.Application, "7-Zip archive"),
        new MimeEntry("bin", "application/octet-stream", MimeCategory.Application, "Binary data"),
        new MimeEntry("exe", "application/x-msdownload", MimeCategory.Application, "Windows executable"),
        new MimeEntry("jar", "application/java-archive", MimeCategory.Application, "Java archive"),
        new MimeEntry("wasm", "application/wasm", MimeCategory.Application, "WebAssembly"),
        new MimeEntry("doc", "application/msword", MimeCategory.Application, "Word document"),
        new MimeEntry("docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", MimeCategory.Application, "Word document (OOXML)"),
        new MimeEntry("xls", "application/vnd.ms-excel", MimeCategory.Application, "Excel spreadsheet"),
        new MimeEntry("xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", MimeCategory.Application, "Excel spreadsheet (OOXML)"),
        new MimeEntry("ppt", "application/vnd.ms-powerpoint", MimeCategory.Application, "PowerPoint"),
        new MimeEntry("pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation", MimeCategory.Application, "PowerPoint (OOXML)"),

        // ── font ────────────────────────────────────────────────────────
        new MimeEntry("woff", "font/woff", MimeCategory.Font, "WOFF font"),
        new MimeEntry("woff2", "font/woff2", MimeCategory.Font, "WOFF2 font"),
        new MimeEntry("ttf", "font/ttf", MimeCategory.Font, "TrueType font"),
        new MimeEntry("otf", "font/otf", MimeCategory.Font, "OpenType font"),
        new MimeEntry("eot", "application/vnd.ms-fontobject", MimeCategory.Application, "Embedded OpenType"),

        // ── multipart ───────────────────────────────────────────────────
        new MimeEntry("mht", "multipart/related", MimeCategory.Multipart, "MHTML web archive"),
        new MimeEntry("mhtml", "multipart/related", MimeCategory.Multipart, "MHTML web archive"),
    };

    /// <summary>Lowercase an extension and drop a leading dot so ".JSON" == "json".</summary>
    public static string NormalizeExt(string ext) =>
        ext.Trim().ToLowerInvariant().TrimStart('.');

    /// <summary>
    /// Every entry whose extension matches. The dot is optional and matching
    /// is case-insensitive, so ".js", "JS", and "js" are equivalent.
    /// Returns an empty list for an unknown/empty extension.
    /// </summary>
    public static IReadOnlyList<MimeEntry> LookupByExt(string ext)
    {
        var e = NormalizeExt(ext);
        if (e.Length == 0) return Array.Empty<MimeEntry>();
        return Mime.Where(m => m.Ext == e).ToArray();
    }

    /// <summary>
    /// Every entry whose MIME matches, case-insensitively, tolerating
    /// surrounding whitespace. One MIME commonly maps to several extensions
    /// (image/jpeg → jpg, jpeg), so all are returned. Empty for unknown/empty.
    /// </summary>
    public static IReadOnlyList<MimeEntry> LookupByMime(string mime)
    {
        var m = mime.Trim().ToLowerInvariant();
        if (m.Length == 0) return Array.Empty<MimeEntry>();
        return Mime.Where(e => e.Mime.ToLowerInvariant() == m).ToArray();
    }

    /// <summary>Optional constraints — null fields are ignored, mirroring
    /// `undefined` fields in the TypeScript source.</summary>
    public sealed record MimeFilter(MimeCategory? Type = null, string? Query = null);

    /// <summary>
    /// Filter the full table by category and/or a free-text query matched
    /// (case-insensitively) against Ext, Mime, and Name. Omitted options are
    /// ignored; an empty query returns the category-filtered set unchanged.
    /// An unknown category value yields nothing (it is not silently coerced).
    /// </summary>
    public static IReadOnlyList<MimeEntry> Filter(MimeFilter? opts = null)
    {
        opts ??= new MimeFilter();
        var q = (opts.Query ?? "").Trim().ToLowerInvariant();
        return Mime.Where(e =>
            (opts.Type is null || e.Type == opts.Type) &&
            (q.Length == 0 ||
             e.Ext.Contains(q, StringComparison.Ordinal) ||
             e.Mime.ToLowerInvariant().Contains(q, StringComparison.Ordinal) ||
             e.Name.ToLowerInvariant().Contains(q, StringComparison.Ordinal)))
            .ToArray();
    }
}

public static class Demo
{
    public static void Main()
    {
        foreach (var e in MimeTable.LookupByExt(".JSON"))
            Console.WriteLine($".JSON -> {e.Mime} ({e.Name})");
        foreach (var e in MimeTable.LookupByMime("IMAGE/JPEG"))
            Console.WriteLine($"image/jpeg -> .{e.Ext}");
        Console.WriteLine(
            $"query \"font\": {MimeTable.Filter(new(Query: "font")).Count} of {MimeTable.Filter().Count} entries");
    }
}

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 →