f-ui
Components

File Type Icon

VS Code style file icons from Iconify vscode-icons by extension or file name, with compound extension matching.

File Type Icon maps a file extension or file name to an Iconify vscode-icons glyph. Pass extension to override parsing from fileName. Unknown extensions use vscode-icons:default-file.

Resolution order when extension is omitted: exact basename (e.g. Dockerfile, docker-compose.yml, compose.yaml) → dotenv (.env, .env.local, …) → hidden single-segment dotfiles (.gitignore → key gitignore) → compound (d.ts, tar.gz) → last extension segment. Typst (.typ) uses material-icon-theme:typst (Iconify can load icons from multiple collections; most keys stay vscode-icons).

Installing

pnpm dlx shadcn@latest add https://ui.isaacfei.com/r/file-type-icon.json
npx shadcn@latest add https://ui.isaacfei.com/r/file-type-icon.json
yarn dlx shadcn@latest add https://ui.isaacfei.com/r/file-type-icon.json
bun x shadcn@latest add https://ui.isaacfei.com/r/file-type-icon.json

With a namespace: npx shadcn@latest add @f-ui/file-type-icon.

Registry dependencies: @iconify/react.

Usage

import { FileTypeIcon } from '@/components/f-ui/file-type-icon/file-type-icon';

<FileTypeIcon fileName="src/App.tsx" />
<FileTypeIcon extension="py" fileName="ignored.ts" />

When aria-label is omitted, the icon is aria-hidden (decorative). Set aria-label if the icon conveys meaning on its own.

Examples

All mapped icons

Icons for every extension key in FILE_TYPE_ICON_BY_EXT (sorted alphabetically).

.accdb
.bash
.binary
.c
.cfg
.cjs
.clj
.compose.yaml
.compose.yml
.conf
.containerfile
.cpp
.cs
.css
.csv
.d.ts
.dart
.doc
.docker
.docker-compose.yaml
.docker-compose.yml
.dockerfile
.dockerignore
.docm
.docx
.dot
.dotm
.dotx
.editorconfig
.env
.erl
.eslint
.ex
.exs
.gif
.gitattributes
.gitignore
.go
.gql
.graphql
.helm
.hs
.htm
.html
.htmx
.ico
.ini
.java
.jpeg
.jpg
.js
.json
.jsonc
.jsx
.kt
.kts
.less
.lock
.log
.lua
.makefile
.md
.mdb
.mdx
.mjs
.nim
.node
.npm
.one
.otf
.pdf
.php
.pl
.pm
.png
.pot
.potx
.pps
.ppsx
.ppt
.pptm
.pptx
.prettier
.prisma
.pub
.py
.pyw
.r
.rb
.rollup
.rs
.sass
.scss
.sh
.sql
.sqlite
.styl
.svelte
.svg
.swift
.tailwind
.tar.bz2
.tar.gz
.tar.xz
.templ
.tex
.toml
.ts
.tsx
.ttf
.txt
.typ
.vite
.vue
.wasm
.webp
.webpack
.woff
.woff2
.xls
.xlsb
.xlsm
.xlsx
.xltx
.xml
.yaml
.yml
.zig
.zip
.zsh
import { FileTypeIcon } from "@/components/f-ui/file-type-icon/file-type-icon";
import { FILE_TYPE_ICON_BY_EXT } from "@/components/f-ui/file-type-icon/vscode-file-type-map";

const EXTENSIONS = Object.keys(FILE_TYPE_ICON_BY_EXT).sort((a, b) =>
  a.localeCompare(b, "en", { sensitivity: "base" }),
);

export function FileTypeIconGalleryDemo() {
  return (
    <div className="grid max-h-[min(70vh,520px)] grid-cols-2 gap-x-4 gap-y-2 overflow-y-auto pr-2 text-sm sm:grid-cols-3 md:grid-cols-4">
      {EXTENSIONS.map((ext) => (
        <div
          key={ext}
          className="flex min-w-0 items-center gap-2 rounded-md border border-border/60 bg-muted/30 px-2 py-1.5"
        >
          <FileTypeIcon extension={ext} size={20} className="shrink-0" />
          <span
            className="text-muted-foreground truncate font-mono text-xs"
            title={ext}
          >
            .{ext}
          </span>
        </div>
      ))}
    </div>
  );
}

From file name

import { FileTypeIcon } from "@/components/f-ui/file-type-icon/file-type-icon";

export function FileTypeIconFilenameDemo() {
  return (
    <div className="flex flex-wrap items-center gap-3">
      <FileTypeIcon fileName="src/App.tsx" />
      <FileTypeIcon fileName="README.md" />
      <FileTypeIcon fileName="data.tar.gz" />
    </div>
  );
}

Extension overrides name

extension overrides file name
import { FileTypeIcon } from "@/components/f-ui/file-type-icon/file-type-icon";

export function FileTypeIconOverrideDemo() {
  return (
    <div className="flex flex-wrap items-center gap-3">
      <FileTypeIcon fileName="main.ts" extension="py" />
      <span className="text-muted-foreground text-xs">
        extension overrides file name
      </span>
    </div>
  );
}

Unknown extension (fallback)

import { FileTypeIcon } from "@/components/f-ui/file-type-icon/file-type-icon";

export function FileTypeIconUnknownDemo() {
  return <FileTypeIcon extension="not-a-real-ext-zzz" />;
}

Compound extension (d.ts)

import { FileTypeIcon } from "@/components/f-ui/file-type-icon/file-type-icon";

export function FileTypeIconCompoundDemo() {
  return <FileTypeIcon fileName="globals.d.ts" />;
}

API Reference

Props

PropTypeDescription
extensionstringOptional. Normalized for lookup; wins over fileName when non-empty after trim/strip.
fileNamestringOptional path or basename; extension is parsed from the basename.
classNamestringClasses on the wrapper span.
sizenumberPixel width/height of the icon. Default 16.
fallbackIconstringFull Iconify id when unknown. Default vscode-icons:default-file.
titlestringNative title tooltip.
aria-labelstringWhen set, the icon is exposed as role="img"; otherwise aria-hidden.

Export DEFAULT_FILE_TYPE_FALLBACK_ICON and resolveFileTypeIconifyId / FILE_TYPE_ICON_BY_EXT live in the same folder for advanced use (custom maps).

On this page