Skip to content

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

// mime-types — Kotlin 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.

/** The seven top-level media types a curated entry can belong to. */
enum class MimeCategory { TEXT, IMAGE, AUDIO, VIDEO, APPLICATION, FONT, MULTIPART }

/** One curated extension ↔ MIME mapping (immutable value object). */
data class MimeEntry(
    val ext: String,   // lowercase, no leading dot (e.g. "json")
    val mime: String,  // full Content-Type (e.g. "application/json")
    val type: MimeCategory, // always the top-level segment of `mime`
    val name: String,  // human-readable format name (e.g. "JSON")
)

/** Optional constraints — null fields are ignored, mirroring `undefined`. */
data class MimeFilter(
    val type: MimeCategory? = null,
    val query: String? = null,
)

object MimeTypes {

    /** Display order of the categories (used by the UI filter). */
    val MIME_CATEGORIES: List<MimeCategory> = MimeCategory.entries

    /**
     * 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.
     */
    val MIME: List<MimeEntry> = listOf(
        // ── text ────────────────────────────────────────────────────────
        MimeEntry("txt", "text/plain", MimeCategory.TEXT, "Plain text"),
        MimeEntry("html", "text/html", MimeCategory.TEXT, "HTML document"),
        MimeEntry("htm", "text/html", MimeCategory.TEXT, "HTML document"),
        MimeEntry("xhtml", "application/xhtml+xml", MimeCategory.APPLICATION, "XHTML"),
        MimeEntry("css", "text/css", MimeCategory.TEXT, "CSS stylesheet"),
        MimeEntry("csv", "text/csv", MimeCategory.TEXT, "Comma-separated values"),
        MimeEntry("xml", "application/xml", MimeCategory.APPLICATION, "XML document"),
        MimeEntry("js", "text/javascript", MimeCategory.TEXT, "JavaScript"),
        MimeEntry("js", "application/javascript", MimeCategory.APPLICATION, "JavaScript (legacy)"),
        MimeEntry("mjs", "text/javascript", MimeCategory.TEXT, "JavaScript module"),
        MimeEntry("json", "application/json", MimeCategory.APPLICATION, "JSON"),
        MimeEntry("md", "text/markdown", MimeCategory.TEXT, "Markdown"),
        MimeEntry("yaml", "text/yaml", MimeCategory.TEXT, "YAML"),
        MimeEntry("yml", "text/yaml", MimeCategory.TEXT, "YAML"),
        MimeEntry("ics", "text/calendar", MimeCategory.TEXT, "iCalendar"),
        MimeEntry("rtf", "application/rtf", MimeCategory.APPLICATION, "Rich text"),
        MimeEntry("tsv", "text/tab-separated-values", MimeCategory.TEXT, "Tab-separated values"),

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

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

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

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

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

        // ── multipart ───────────────────────────────────────────────────
        MimeEntry("mht", "multipart/related", MimeCategory.MULTIPART, "MHTML web archive"),
        MimeEntry("mhtml", "multipart/related", MimeCategory.MULTIPART, "MHTML web archive"),
    )

    /** Lowercase an extension and drop a leading dot so ".JSON" == "json". */
    fun normalizeExt(ext: String): String =
        ext.trim().lowercase().trimStart('.')

    /**
     * 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.
     */
    fun lookupByExt(ext: String): List<MimeEntry> {
        val e = normalizeExt(ext)
        if (e.isEmpty()) return emptyList()
        return MIME.filter { it.ext == e }
    }

    /**
     * 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.
     */
    fun lookupByMime(mime: String): List<MimeEntry> {
        val m = mime.trim().lowercase()
        if (m.isEmpty()) return emptyList()
        return MIME.filter { it.mime.lowercase() == m }
    }

    /**
     * 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).
     */
    fun filter(opts: MimeFilter = MimeFilter()): List<MimeEntry> {
        val q = (opts.query ?: "").trim().lowercase()
        return MIME.filter { e ->
            (opts.type == null || e.type == opts.type) &&
                (q.isEmpty() || q in e.ext.lowercase() || q in e.mime.lowercase() || q in e.name.lowercase())
        }
    }
}

fun main() {
    MimeTypes.lookupByExt(".JSON").forEach { println(".JSON -> ${it.mime} (${it.name})") }
    MimeTypes.lookupByMime("IMAGE/JPEG").forEach { println("image/jpeg -> .${it.ext}") }
    println("query \"font\": ${MimeTypes.filter(MimeFilter(query = "font")).size} of ${MimeTypes.MIME.size} 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 →