# mime-types for Node.js MIME Lookup and Header Generation

> mime-types is a Node.js library for mapping extensions to MIME types, creating Content-Type values, and resolving default charsets. Its strict false return value and compatibility with the mime 1.x API make it suitable for applications that need predictable handling of failed lookups.

**jshttp/mime-types** — The ultimate javascript content-type utility.

- Repository: https://github.com/jshttp/mime-types
- Stars: 1,479 · Forks: 153
- Language: JavaScript
- License: MIT
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/jshttp-mime-types

## Strict MIME Resolution in mime-types

mime-types addresses a narrow problem in Node.js applications: turning a filename, extension, or media type into a value that can inform an HTTP response or another protocol decision. It is aimed at developers who need MIME lookup without constructing a mutable MIME registry. The package exposes synchronous functions for looking up a file type, creating a complete Content-Type value, finding a default extension, and checking the implied charset.

The defining design choice is its refusal to guess. An unrecognized input produces false rather than an arbitrary MIME type. The README explicitly contrasts this with the mime@1.x module, which could return the first available fallback type. Applications using mime-types therefore retain control over policy. A web server may choose application/octet-stream after a failed lookup, while another service may reject the request or return a different status. That decision remains outside the utility.

This strict behavior also applies to dotfiles. `mime.lookup('folder/.htaccess')` returns false because the extension is not recognized, even though the input contains a dot. Ordinary recognized names such as `file.html`, `folder/file.js`, and `.md` produce their associated media types. Unknown names such as `cats` follow the same false-return contract. This is useful when a missing mapping must not be confused with a generic file response.

The package retains compatibility with the programmatic API of mime 1.x, but that compatibility does not include every feature. There is no `new Mime()` construction pattern and no `.define()` method for registering custom records. Code that mutates MIME definitions through those APIs would need another approach. The public functions remain available through `require('mime-types')`, with individual functions exported as properties such as `mime.lookup`, `mime.contentType`, `mime.extension`, and `mime.charset`.

## mime-db Data Flow and mime-types API

The MIME records come from the separate mime-db package, which `package.json` declares as a dependency with the range `^1.54.0`. The README states that all MIME types are based on mime-db and that requests for additional types should be submitted upstream through a pull request to that project. This separates program behavior from the data used to answer extension and media-type queries.

Four operations form the core API. `mime.lookup(path)` associates a file or extension with a content type. The documented results include `json` becoming `application/json`, `.md` becoming `text/markdown`, `file.html` becoming `text/html`, and `folder/file.js` becoming `text/javascript`. Every function returns false if its input is invalid or cannot be found.

`mime.contentType(type)` accepts either an extension or a content type. For an extension, it calls `mime.lookup`; otherwise, it uses the supplied content type. It then checks for an existing `charset` parameter. If none is present, it calls `mime.charset` and adds the returned charset when one is available. As a result, `contentType('file.json')` becomes `application/json; charset=utf-8`, while a value already carrying `charset=iso-8859-1` retains that parameter.

The inverse operations are narrower. `mime.extension(type)` returns the default extension for a media type, with `application/octet-stream` mapped to `bin`. `mime.charset(type)` returns the implied default charset, such as `UTF-8` for `text/markdown`. The package also exposes `mime.types`, a map keyed by extension, and `mime.extensions`, a map keyed by content type. The README does not document mutation behavior for those maps, and `.define()` is explicitly absent.

## Installing mime-types and Performing the First Lookup

The README identifies npm as the installation route and gives a local package installation command. The current package metadata requires Node.js `>=18`, so an older runtime should be checked before installation.

Run the documented command inside the Node.js project that needs the package:

```sh
$ npm install mime-types
```

After installation, require the package with the API shown in the README:

```js
var mime = require('mime-types')
```

A first lookup can use one of the exact examples documented for `mime.lookup(path)`:

```js
mime.lookup('json') // 'application/json'
mime.lookup('.md') // 'text/markdown'
mime.lookup('file.html') // 'text/html'
mime.lookup('folder/file.js') // 'text/javascript'
mime.lookup('folder/.htaccess') // false

mime.lookup('cats') // false
```

The expected values are the MIME strings and false results shown in the comments. The final two examples demonstrate that an unrecognized dotfile and an unknown bare name both fail rather than receiving a fallback.

For callers that want a header-ready value, the README provides the `mime.contentType(type)` examples. Passing a filename uses its extension, and the returned value includes a charset when the documentation defines one:

```js
mime.contentType('markdown') // 'text/x-markdown; charset=utf-8'
mime.contentType('file.json') // 'application/json; charset=utf-8'
mime.contentType('text/html') // 'text/html; charset=utf-8'
mime.contentType('text/html; charset=iso-8859-1') // 'text/html; charset=iso-8859-1'

// from a full path
mime.contentType(path.extname('/path/to/file.json')) // 'application/json; charset=utf-8'
```

The full-path example assumes that the caller has supplied `path`, such as through Node.js's `path` module. The README does not give a complete executable wrapper for that example.

## Explicit Fallbacks for Unknown MIME Lookups

mime-types makes the fallback decision visible in application code. That is a meaningful difference from the mime@1.x package as summarized by the README. Instead of returning the first available type, mime-types returns false. The caller can then apply a policy that matches the service.

The README provides a direct pattern for this case. It assigns the result of `mime.lookup('unrecognized')` to `type` and falls back to `application/octet-stream` when that result is false. This does not configure the library to use that fallback. The application chooses the value on each call.

That distinction matters in HTTP handlers. A download endpoint may accept unknown extensions as binary files, while an API that serves user-authored pages may reject them. A service may also record the failed lookup or require an explicit allowlist. None of those policies is imposed by the package.

The strict contract also affects chained calls. A result from `mime.lookup(path)` must be checked before code tries to treat it as a MIME string. Directly appending `charset` to an unknown lookup result would operate on false rather than generate a safe header. The documented pattern avoids that failure by handling false before further use.

This behavior makes sense for small libraries because MIME defaults can change the meaning of a response. Returning application/octet-stream without an application decision may be acceptable for some services and incorrect for others. mime-types keeps that decision in the application, which is especially useful when the same package handles downloads, static assets, and protocol-specific responses.

## Changing mime-db Data Across Upgrades

The package makes an unusual version compatibility statement. It treats its programmatic API as the semver contract, but MIME resolution results are outside that contract. Since resolution data comes from mime-db, the answer for an extension or media type may change when that dependency receives updated data.

`package.json` currently allows `mime-db` through `^1.54.0`. The README says mime-types may update mime-db as a minor release when needed and will use a caret range. Applications that need reproducible MIME results must pin the relevant mime-db data in their own package manager configuration. The README specifically points to package-manager overrides for this purpose, without prescribing one syntax because package managers differ.

This policy affects upgrades more than ordinary API adoption. A change in a resolved type can alter response headers without representing a breaking change to the programmatic API. Applications with exact response expectations or project-specific MIME requirements should therefore review dependency changes as well as mime-types version changes.

Recent releases include v3.0.0 and v3.0.1 in March 2025, followed by v3.0.2 in November 2025. The repository is not archived, and the last push was on 2026-06-02. That status shows recent repository activity, but it does not remove the documented data-change boundary. Pinning remains an application-level decision when deterministic output is required.

The MIT license permits use and modification under its terms, subject to the license conditions. License review still belongs to the adopting organization. More important for this library is whether dependency review accounts for mime-db updates that can affect application output without changing mime-types' API contract.

## When mime-types Is the Wrong Choice

The clearest wrong-tool case is runtime-defined MIME handling. mime-types does not provide `.define()`, so code that expects to add a custom extension and content-type mapping to its shared registry cannot use that feature. Since the README says new MIME records belong in mime-db, a project needing custom records must maintain its own mapping or choose another approach.

It is also unsuitable for code that expects silent fallback behavior. A caller that assumes every lookup produces a MIME string can fail when the result is false. Developers need explicit handling for unknown files and invalid inputs. This is stricter than systems designed to assign application/octet-stream automatically.

This is a lookup library, not a file inspector. Its examples operate on names or extensions. The README does not describe reading file contents, identifying media types from binary signatures, or combining declared upload metadata with observed file data. An application needing content-based inspection requires separate functionality.

For a fixed set of project-specific types, a direct lookup table may be clearer. Such a table can map extensions to Content-Type values without depending on changing mime-db records. mime-types is more relevant when the application wants the existing mime-db dataset and a compact functional API rather than a mutable registry. The choice turns on whether shared MIME data is useful or predictable project-specific control is the priority.

## MIT Packaging and Node.js Verification

The repository identifies the package under the MIT License and includes a LICENSE file. The documented examples use CommonJS through `require`, matching the API shown in the README. The published `files` list includes `HISTORY.md`, `LICENSE`, `index.js`, and `mimeScore.js`, while mime-db is installed as a dependency.

There is no documented native binding, external service, database server, or background process. Integration is centered on dependency management, calling the exported functions, and handling false. Node.js compatibility is concrete: `package.json` declares `>=18`. Applications using an older runtime should verify that requirement before adopting version 3.0.2.

The repository also declares scripts for linting and tests. The test script invokes Mocha directly:

```json
"test": "mocha --reporter spec test/test.js"
```

This value is copied from the `scripts` object in `package.json`. The same file defines `lint`, `test-ci`, and `test-cov`, but those scripts describe repository maintenance rather than runtime use by an installed application. This review did not execute them.

Before adopting the package, confirm that Node.js 18 or newer is available, inspect whether existing code expects fallback behavior, and review the project's package-manager policy for pinning mime-db. Those checks address the package's actual boundaries rather than relying on its broad description as a general content-type utility.

## Conclusion

Adopt mime-types when a Node.js application needs small, synchronous helpers for extension lookup, Content-Type generation, default extensions, and charset resolution. Do not choose it if you need runtime MIME registration or automatic fallback to application/octet-stream. Before adoption, verify the Node.js 18 requirement, decide how your application will handle false, and determine whether changing mime-db data must be pinned through your package manager.

## FAQ

### How do I install mime-types in a Node.js project?

The README instructs users to run `npm install mime-types`. The current package metadata requires Node.js 18 or newer.

### What does mime-types return for an unknown file extension?

It returns false. The README says this prevents fallback guessing and gives `application/octet-stream` as an application-controlled fallback example.

### Can I add custom MIME types to mime-types at runtime?

No. The README explicitly lists `.define()` as unsupported. It says all MIME types are based on mime-db and directs additions to a pull request in that upstream project.

## Sources

- [Issues](https://github.com/jshttp/mime-types/issues)
- [jshttp/mime-types on GitHub](https://github.com/jshttp/mime-types)
- [License: MIT](https://github.com/jshttp/mime-types/blob/master/LICENSE)
- [README](https://github.com/jshttp/mime-types/blob/master/README.md)
- [Releases](https://github.com/jshttp/mime-types/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/jshttp-mime-types
