MIME type detection and content-type helpers for Remix. This package maps extensions to MIME types and provides utilities for charset and compressibility checks.
Installation
Features
- MIME Detection - Detect MIME types from extensions and filenames
- Content-Type Helpers - Build Content-Type values with charset handling
- Compression Signals - Check whether a media type is likely compressible
- Generated Data - Built from mime-db
- Runtime Agnostic - Works everywhere JavaScript runs
API Reference
detectMimeType
Detects the MIME type for a given file extension or filename.
function detectMimeType(
extension: string
): string | undefined
File extension (with or without dot) or filename with path.
The MIME type for the extension, or undefined if unknown.
import { detectMimeType } from 'remix/mime'
detectMimeType('txt') // 'text/plain'
detectMimeType('.txt') // 'text/plain'
detectMimeType('file.txt') // 'text/plain'
detectMimeType('path/to/file.txt') // 'text/plain'
detectMimeType('unknown') // undefined
detectContentType
Detects the Content-Type header value for a given file extension or filename, including charset for text-based types.
function detectContentType(
extension: string
): string | undefined
File extension (with or without dot) or filename with path.
The Content-Type header value with charset if applicable, or undefined if unknown.
import { detectContentType } from 'remix/mime'
detectContentType('css') // 'text/css; charset=utf-8'
detectContentType('.json') // 'application/json; charset=utf-8'
detectContentType('image.png') // 'image/png'
detectContentType('path/to/file.unknown') // undefined
isCompressibleMimeType
Checks if a MIME type is known to be compressible.
function isCompressibleMimeType(
mimeType: string
): boolean
MIME type or full Content-Type header value.
true if the MIME type is compressible, false otherwise.
import { isCompressibleMimeType } from 'remix/mime'
isCompressibleMimeType('text/html') // true
isCompressibleMimeType('application/json') // true
isCompressibleMimeType('image/png') // false
isCompressibleMimeType('video/mp4') // false
// Also accepts full Content-Type header values
isCompressibleMimeType('text/html; charset=utf-8') // true
isCompressibleMimeType('application/json; charset=utf-8') // true
mimeTypeToContentType
Converts a MIME type to a Content-Type header value, adding ; charset=utf-8 to text-based MIME types.
function mimeTypeToContentType(
mimeType: string
): string
The MIME type to convert.
The Content-Type header value with charset if applicable.
Charset is added to:
text/* (except text/xml which has built-in encoding declarations)
application/json
application/javascript
- All
+json suffixed types
import { mimeTypeToContentType } from 'remix/mime'
mimeTypeToContentType('text/css') // 'text/css; charset=utf-8'
mimeTypeToContentType('application/json') // 'application/json; charset=utf-8'
mimeTypeToContentType('application/ld+json') // 'application/ld+json; charset=utf-8'
mimeTypeToContentType('image/png') // 'image/png'
mimeTypeToContentType('text/xml') // 'text/xml' (no charset added)
defineMimeType
Registers or overrides a MIME type for one or more file extensions.
function defineMimeType(
definition: MimeTypeDefinition
): void
definition
MimeTypeDefinition
required
The MIME type definition to register.
MimeTypeDefinition
Array of file extensions (without dots) to associate with this MIME type.
Whether the MIME type is compressible.Default: false
The charset to use in Content-Type headers.Default: undefined
import { defineMimeType } from 'remix/mime'
// Basic definition
defineMimeType({
extensions: ['myformat'],
mimeType: 'application/x-myformat',
})
// With charset and compressibility
defineMimeType({
extensions: ['myformat', 'myfmt'],
mimeType: 'application/x-myformat',
compressible: true,
charset: 'utf-8',
})
Examples
Detect MIME Type from Filename
import { detectMimeType } from 'remix/mime'
function getMimeType(filename: string): string {
return detectMimeType(filename) ?? 'application/octet-stream'
}
getMimeType('document.pdf') // 'application/pdf'
getMimeType('image.jpg') // 'image/jpeg'
getMimeType('styles.css') // 'text/css'
getMimeType('unknown.xyz') // 'application/octet-stream'
import { detectContentType } from 'remix/mime'
let filename = 'document.json'
let contentType = detectContentType(filename)
let response = new Response(data, {
headers: {
'Content-Type': contentType ?? 'application/octet-stream',
},
})
Conditional Compression
import { isCompressibleMimeType } from 'remix/mime'
import { compressResponse } from 'remix/response/compress'
let response = new Response(data, {
headers: { 'Content-Type': contentType },
})
if (isCompressibleMimeType(contentType)) {
response = await compressResponse(response, request)
}
Custom MIME Type
import { defineMimeType, detectMimeType } from 'remix/mime'
// Register custom format
defineMimeType({
extensions: ['mdx'],
mimeType: 'text/mdx',
compressible: true,
charset: 'utf-8',
})
detectMimeType('document.mdx') // 'text/mdx'
File Upload Handler
import { detectMimeType, isCompressibleMimeType } from 'remix/mime'
function shouldCompress(filename: string): boolean {
let mimeType = detectMimeType(filename)
return mimeType ? isCompressibleMimeType(mimeType) : false
}
shouldCompress('document.txt') // true
shouldCompress('image.png') // false
shouldCompress('data.json') // true
Serve Static Files
import { detectContentType } from 'remix/mime'
import { createFileResponse } from 'remix/response/file'
import { openLazyFile } from 'remix/fs'
async function serveFile(path: string, request: Request): Promise<Response> {
let file = openLazyFile(path)
// The file's type is automatically detected from the extension
// but you can also use detectContentType if needed
let contentType = detectContentType(path) ?? 'application/octet-stream'
return createFileResponse(file, request, {
cacheControl: 'public, max-age=3600',
})
}
Common MIME Types
Text
detectMimeType('txt') // 'text/plain'
detectMimeType('html') // 'text/html'
detectMimeType('css') // 'text/css'
detectMimeType('csv') // 'text/csv'
detectMimeType('xml') // 'text/xml'
Application
detectMimeType('json') // 'application/json'
detectMimeType('js') // 'application/javascript'
detectMimeType('pdf') // 'application/pdf'
detectMimeType('zip') // 'application/zip'
detectMimeType('wasm') // 'application/wasm'
Image
detectMimeType('png') // 'image/png'
detectMimeType('jpg') // 'image/jpeg'
detectMimeType('jpeg') // 'image/jpeg'
detectMimeType('gif') // 'image/gif'
detectMimeType('svg') // 'image/svg+xml'
detectMimeType('webp') // 'image/webp'
detectMimeType('ico') // 'image/x-icon'
Video
detectMimeType('mp4') // 'video/mp4'
detectMimeType('webm') // 'video/webm'
detectMimeType('mov') // 'video/quicktime'
Audio
detectMimeType('mp3') // 'audio/mpeg'
detectMimeType('wav') // 'audio/wav'
detectMimeType('ogg') // 'audio/ogg'
Font
detectMimeType('woff') // 'font/woff'
detectMimeType('woff2') // 'font/woff2'
detectMimeType('ttf') // 'font/ttf'
detectMimeType('otf') // 'font/otf'
Type Definitions
function detectMimeType(extension: string): string | undefined
function detectContentType(extension: string): string | undefined
function isCompressibleMimeType(mimeType: string): boolean
function mimeTypeToContentType(mimeType: string): string
interface MimeTypeDefinition {
extensions: string[]
mimeType: string
compressible?: boolean
charset?: string
}
function defineMimeType(definition: MimeTypeDefinition): void
Best Practices
Always Provide Fallback
// ✅ Good: Provide fallback for unknown types
let mimeType = detectMimeType(filename) ?? 'application/octet-stream'
// ❌ Bad: May result in undefined
let mimeType = detectMimeType(filename)
// ✅ Good: Use detectContentType for headers (includes charset)
let contentType = detectContentType('file.json')
// 'application/json; charset=utf-8'
// ❌ Less ideal: detectMimeType doesn't include charset
let mimeType = detectMimeType('file.json')
// 'application/json'
Check Compressibility
// ✅ Good: Check before enabling compression features
let acceptRanges = !isCompressibleMimeType(file.type)
let response = await createFileResponse(file, request, {
acceptRanges, // Enable ranges only for non-compressible types
})
- response - Uses MIME utilities for file responses
- lazy-file - File implementation with MIME type support