Skip to main content

Overview

The normalizeMimeType function converts non-standard, vendor-specific, or legacy MIME types to their canonical, standardized forms. This ensures consistency when working with file formats across different handlers and sources.

Import

import normalizeMimeType from "./normalizeMimeType.ts";

Function Signature

function normalizeMimeType(mime: string): string
mime
string
required
The MIME type string to normalize
returns
string
The normalized MIME type, or the original string if no normalization is needed

Normalization Mappings

The function handles the following MIME type normalizations:

Audio Formats

Non-Standard MIME TypeCanonical MIME TypeNotes
audio/x-wavaudio/wavLegacy WAV prefix
audio/vnd.waveaudio/wavVendor-specific WAV
application/oggaudio/oggOGG misidentified as application
audio/x-flacaudio/flacLegacy FLAC prefix
audio/x-quicktimevideo/quicktimeQuickTime audio is actually video
audio/x-floaudio/floLegacy FLO prefix
application/x-floaudio/floFLO misidentified as application
video/binkaaudio/vnd.radgamettools.binkBink audio format
video/brstmaudio/brstmBRSTM misidentified as video

Video Formats

Non-Standard MIME TypeCanonical MIME TypeNotes
video/binkvideo/vnd.radgamettools.binkRAD Game Tools Bink video

Image Formats

Non-Standard MIME TypeCanonical MIME TypeNotes
image/x-icnsimage/icnsmacOS icon format
image/x-iconimage/vnd.microsoft.iconWindows icon format
image/vtfimage/x-vtfValve Texture Format
image/asepriteimage/x-asepriteAseprite sprite format
application/x-asepriteimage/x-asepriteAseprite misidentified
image/qoiimage/x-qoiQuite OK Image format

Archive Formats

Non-Standard MIME TypeCanonical MIME TypeNotes
application/x-gzipapplication/gzipLegacy GZIP prefix
application/x-lharcapplication/x-lzh-compressedLHarc archive
application/lhaapplication/x-lzh-compressedLHA archive
application/x-lhaapplication/x-lzh-compressedLHA variant
application/x-lzhapplication/x-lzh-compressedLZH variant

Font Formats

Non-Standard MIME TypeCanonical MIME TypeNotes
application/font-sfntfont/ttfSFNT-based fonts
application/x-font-ttffont/ttfLegacy TrueType/OpenType
application/x-font-opentypefont/otfLegacy OpenType
application/font-wofffont/woffWOFF fonts
application/x-font-wofffont/woffLegacy WOFF prefix
application/font-woff2font/woff2WOFF2 fonts
application/x-font-woff2font/woff2Legacy WOFF2 prefix

Document Formats

Non-Standard MIME TypeCanonical MIME TypeNotes
application/musicxmlapplication/vnd.recordare.musicxml+xmlMusicXML
application/musicxml+xmlapplication/vnd.recordare.musicxml+xmlMusicXML variant
text/mathmlapplication/mathml+xmlMathML format

Database Formats

Non-Standard MIME TypeCanonical MIME TypeNotes
application/x-mtgaapplication/vnd.sqlite3Magic: The Gathering Arena DB
application/x-itunes-itdbapplication/vnd.sqlite3iTunes database

Usage Examples

Basic Usage

import normalizeMimeType from "./normalizeMimeType.ts";

// Normalize legacy audio MIME type
const normalized = normalizeMimeType("audio/x-wav");
console.log(normalized); // "audio/wav"

// Normalize font MIME type
const fontMime = normalizeMimeType("application/x-font-ttf");
console.log(fontMime); // "font/ttf"

// No normalization needed - returns original
const standard = normalizeMimeType("image/png");
console.log(standard); // "image/png"

Integration with Format Detection

import mime from "mime";
import normalizeMimeType from "./normalizeMimeType.ts";

function detectFileType(filename: string): string {
  const detectedMime = mime.getType(filename) || "application/octet-stream";
  return normalizeMimeType(detectedMime);
}

const type1 = detectFileType("song.wav");
// Even if mime library returns "audio/x-wav", we get "audio/wav"

const type2 = detectFileType("font.woff2");
// Normalizes to "font/woff2" regardless of detected variant

FFmpeg Handler Integration

Real-world example from the FFmpeg handler (src/handlers/FFmpeg.ts:7):
import mime from "mime";
import normalizeMimeType from "../normalizeMimeType.ts";
import CommonFormats from "src/CommonFormats.ts";

class FFmpegHandler implements FormatHandler {
  async init() {
    // Get MIME types from file-type library and normalize them
    const formats = await this.detectFormats();
    
    this.supportedFormats = formats.map(format => {
      const detectedMime = mime.getType(format.extension);
      const normalizedMime = normalizeMimeType(detectedMime || "");
      
      return {
        ...format,
        mime: normalizedMime
      };
    });
  }
}

Format Comparison

import normalizeMimeType from "./normalizeMimeType.ts";

function isSameFormat(mime1: string, mime2: string): boolean {
  return normalizeMimeType(mime1) === normalizeMimeType(mime2);
}

// These are considered the same format
console.log(isSameFormat("audio/x-wav", "audio/wav")); // true
console.log(isSameFormat("audio/vnd.wave", "audio/wav")); // true

// These are different
console.log(isSameFormat("audio/wav", "audio/mp3")); // false

File Upload Handler

import normalizeMimeType from "./normalizeMimeType.ts";

function processUpload(file: File) {
  // Browser-provided MIME types can vary
  const browserMime = file.type;
  const standardMime = normalizeMimeType(browserMime);
  
  // Use standardMime for consistent format handling
  return {
    name: file.name,
    mime: standardMime,
    size: file.size
  };
}

Creating Custom Handlers with Normalized MIME

import normalizeMimeType from "./normalizeMimeType.ts";
import type { FileFormat, FormatHandler } from "../FormatHandler.ts";

class CustomHandler implements FormatHandler {
  name = "CustomHandler";
  supportedFormats: FileFormat[] = [];
  ready = false;

  async init() {
    const inputMimes = [
      "audio/x-flac",
      "application/x-font-woff2",
      "image/x-icon"
    ];

    this.supportedFormats = inputMimes.map(mime => ({
      name: "Custom Format",
      format: "custom",
      extension: "custom",
      mime: normalizeMimeType(mime), // Normalized for consistency
      internal: "custom",
      from: true,
      to: true,
      lossless: false
    }));
    
    this.ready = true;
  }

  async doConvert(/* ... */) {
    // Implementation
  }
}

Why Normalization Matters

Consistency Across Sources

Different file type detection libraries, browsers, and operating systems may report different MIME types for the same format. Normalization ensures your application treats these variants consistently.

Handler Compatibility

When multiple handlers support the same format, normalization ensures they all use the same MIME type identifier, making format matching and conversion routing work reliably.

Future-Proofing

As MIME type standards evolve and vendor-specific types become standardized, this function provides a central place to update mappings without changing code throughout your application.

Common Pitfalls

Don’t Skip Normalization

// BAD: Direct MIME comparison without normalization
if (file.type === "audio/wav") {
  // Fails if file.type is "audio/x-wav" or "audio/vnd.wave"
}

// GOOD: Normalize before comparison
if (normalizeMimeType(file.type) === "audio/wav") {
  // Works with all WAV variants
}

Normalize External Input

import normalizeMimeType from "./normalizeMimeType.ts";

// BAD: Trust external MIME types directly
function handleUpload(mimeType: string) {
  return lookupHandler(mimeType); // May fail with non-standard types
}

// GOOD: Normalize first
function handleUpload(mimeType: string) {
  const normalized = normalizeMimeType(mimeType);
  return lookupHandler(normalized);
}

See Also

Build docs developers (and LLMs) love