denji
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseManaging SVG Icons with Denji
使用Denji管理SVG图标
Denji converts Iconify SVG icons into typed framework components. Icons are fetched, optimized (SVGO), and generated as native components for your framework.
Denji可将Iconify SVG图标转换为类型化的框架组件。图标会被获取、优化(通过SVGO)并生成为适配你所用框架的原生组件。
Core Workflow
核心工作流
bash
undefinedbash
undefined1. Initialize project
1. 初始化项目
npx denji init --framework react --output ./src/icons.tsx
npx denji init --framework react --output ./src/icons.tsx
2. Add icons (prefix:name format from Iconify)
2. 添加图标(采用Iconify的prefix:name格式)
npx denji add lucide:check lucide:x lucide:arrow-right
npx denji add lucide:check lucide:x lucide:arrow-right
3. Use in your code
3. 在代码中使用
```tsx
import { Icons } from "./icons";
<Icons.Check className="size-4 text-green-500" />
<Icons.X className="size-4 text-red-500" />
```tsx
import { Icons } from "./icons";
<Icons.Check className="size-4 text-green-500" />
<Icons.X className="size-4 text-red-500" />Commands
命令
denji init
denji initdenji init
denji initInitialize a Denji project. Creates config and icons template.
denji.jsonbash
npx denji init
npx denji init --framework react --output ./src/icons.tsx
npx denji init --framework svelte --output ./src/icons --output-type folder
npx denji init --framework react --no-typescript --output ./src/icons.jsx
npx denji init --a11y hidden --forward-ref| Flag | Description |
|---|---|
| |
| Output path for icons file/folder |
| |
| TypeScript or JavaScript (default: TS) |
| |
| Use forwardRef (React/Preact only) |
| Track Iconify source via |
| Working directory |
Missing flags trigger interactive prompts.
初始化Denji项目。创建配置文件和图标模板。
denji.jsonbash
npx denji init
npx denji init --framework react --output ./src/icons.tsx
npx denji init --framework svelte --output ./src/icons --output-type folder
npx denji init --framework react --no-typescript --output ./src/icons.jsx
npx denji init --a11y hidden --forward-ref| 标志 | 描述 |
|---|---|
| 可选值: |
| 图标文件/文件夹的输出路径 |
| 可选值: |
| 使用TypeScript或JavaScript(默认:TS) |
| 可选值: |
| 使用forwardRef(仅适用于React/Preact) |
| 通过 |
| 工作目录 |
缺失的标志会触发交互式提示。
denji add <icons...>
denji add <icons...>denji add <icons...>
denji add <icons...>Add icons from Iconify. Icons use format.
prefix:namebash
npx denji add lucide:check
npx denji add lucide:check mdi:home radix-icons:cross-2
npx denji add lucide:star --name FavoriteStar
npx denji add lucide:info --a11y img从Iconify添加图标。图标采用格式。
prefix:namebash
npx denji add lucide:check
npx denji add lucide:check mdi:home radix-icons:cross-2
npx denji add lucide:star --name FavoriteStar
npx denji add lucide:info --a11y imgPreview without writing files
预览操作而不写入文件
npx denji add lucide:check mdi:home --dry-run
| Flag | Description |
|------|-------------|
| `--name <name>` | Custom component name (single icon only) |
| `--a11y <strategy>` | Override a11y strategy for this icon |
| `--dry-run` | Preview what would be generated without writing any files |
| `-c, --cwd <path>` | Working directory |
Icon naming: `lucide:arrow-right` becomes `ArrowRight` (PascalCase). Override with `--name`.
Adding an existing icon updates it in place.
`--dry-run` skips file writes and hooks but still validates icon names, `allowedLibraries`, and config. Useful for CI checks and PR previews.
◇ denji add
│
○ [dry-run] Would add Check → ./src/icons.tsx
○ [dry-run] Would add Home → ./src/icons.tsx
│
◇ Dry run complete — 2 icon(s) previewed, no files written
undefinednpx denji add lucide:check mdi:home --dry-run
| 标志 | 描述 |
|------|-------------|
| `--name <name>` | 自定义组件名称(仅适用于单个图标) |
| `--a11y <strategy>` | 覆盖此图标的无障碍策略 |
| `--dry-run` | 预览将生成的内容,但不写入任何文件 |
| `-c, --cwd <path>` | 工作目录 |
图标命名规则:`lucide:arrow-right`会转换为`ArrowRight`(大驼峰格式)。可通过`--name`参数覆盖命名。
添加已存在的图标会原地更新该图标。
`--dry-run`会跳过文件写入和钩子,但仍会验证图标名称、`allowedLibraries`和配置。适用于CI检查和PR预览。
◇ denji add
│
○ [dry-run] 将会添加 Check → ./src/icons.tsx
○ [dry-run] 将会添加 Home → ./src/icons.tsx
│
◇ 试运行完成 — 预览了2个图标,未写入任何文件
undefineddenji remove <icons...>
denji remove <icons...>denji remove <icons...>
denji remove <icons...>Remove icons by component name. Aliases: , , .
rmdeletedelbash
npx denji remove Check
npx denji rm Check Home ArrowRight| Flag | Description |
|---|---|
| Working directory |
按组件名称删除图标。别名:, , 。
rmdeletedelbash
npx denji remove Check
npx denji rm Check Home ArrowRight| 标志 | 描述 |
|---|---|
| 工作目录 |
denji list
denji listdenji list
denji listList all icons in your project.
bash
npx denji list
npx denji list --display json
npx denji list --display toon| Flag | Description |
|---|---|
| Output mode: |
| Working directory |
Shows component names and Iconify source (if ).
trackSource: trueDefault output:
Found 3 icon(s) in ./src/icons.tsx
Icons:
• Check (lucide:check)
• HomeOutline (mdi:home-outline)
• ArrowRight (lucide:arrow-right)JSON output ():
--display jsonjson
{
"count": 3,
"output": "./src/icons.tsx",
"icons": [
{ "name": "Check", "source": "lucide:check" },
{ "name": "HomeOutline", "source": "mdi:home-outline" },
{ "name": "ArrowRight", "source": "lucide:arrow-right" }
]
}TOON output () uses TOON format for machine-readable binary encoding.
--display toon列出项目中的所有图标。
bash
npx denji list
npx denji list --display json
npx denji list --display toon| 标志 | 描述 |
|---|---|
| 输出模式: |
| 工作目录 |
显示组件名称和Iconify源(当时)。
trackSource: true默认输出:
在 ./src/icons.tsx 中找到3个图标
图标列表:
• Check (lucide:check)
• HomeOutline (mdi:home-outline)
• ArrowRight (lucide:arrow-right)JSON输出():
--display jsonjson
{
"count": 3,
"output": "./src/icons.tsx",
"icons": [
{ "name": "Check", "source": "lucide:check" },
{ "name": "HomeOutline", "source": "mdi:home-outline" },
{ "name": "ArrowRight", "source": "lucide:arrow-right" }
]
}TOON输出()使用TOON格式进行机器可读的二进制编码。
--display toondenji export
denji exportdenji export
denji exportExport a JSON manifest of all tracked icons.
bash
npx denji export # print to stdout
npx denji export --output icons.json
npx denji export --output # writes to denji-export.json| Flag | Description |
|---|---|
| Write to file (default: |
| Working directory |
Output format:
json
{
"version": 1,
"framework": "react",
"output": "./src/icons.tsx",
"icons": [
{ "name": "Home", "source": "mdi:home" },
{ "name": "Check", "source": "lucide:check" }
]
}sourcetrackSource: true导出所有已跟踪图标的JSON清单。
bash
npx denji export # 打印到标准输出
npx denji export --output icons.json
npx denji export --output # 写入到 denji-export.json| 标志 | 描述 |
|---|---|
| 写入到文件(如果未指定路径,默认写入 |
| 工作目录 |
输出格式:
json
{
"version": 1,
"framework": "react",
"output": "./src/icons.tsx",
"icons": [
{ "name": "Home", "source": "mdi:home" },
{ "name": "Check", "source": "lucide:check" }
]
}仅当(默认值)时才会包含字段。
trackSource: truesourcedenji import
denji importdenji import
denji importBulk-add icons from a manifest JSON file, a plain text file, or stdin.
bash
npx denji import icons.json # from denji export manifest
npx denji import icons.txt # one prefix:name per line
echo "mdi:home\nlucide:check" | npx denji import # from stdin
npx denji import icons.json --dry-run| Flag | Description |
|---|---|
| Preview without writing files |
| Working directory |
Icons without format are skipped with a warning. JSON manifest entries without a field are also skipped.
prefix:namesource从清单JSON文件、纯文本文件或标准输入批量添加图标。
bash
npx denji import icons.json # 来自denji导出的清单
npx denji import icons.txt # 每行一个prefix:name格式的图标
echo "mdi:home\nlucide:check" | npx denji import # 来自标准输入
npx denji import icons.json --dry-run| 标志 | 描述 |
|---|---|
| 预览操作而不写入文件 |
| 工作目录 |
不符合格式的图标会被跳过并发出警告。JSON清单中没有字段的条目也会被跳过。
prefix:namesourcedenji clear
denji cleardenji clear
denji clearRemove all icons. Aliases: , .
clrresetbash
npx denji clear
npx denji clear --yes| Flag | Description |
|---|---|
| Skip confirmation prompt |
| Working directory |
删除所有图标。别名:, 。
clrresetbash
npx denji clear
npx denji clear --yes| 标志 | 描述 |
|---|---|
| 跳过确认提示 |
| 工作目录 |
Config (denji.json
)
denji.json配置文件(denji.json
)
denji.jsonThe field depends on how Denji is installed:
$schema- Locally installed ():
npm i -D denji"./node_modules/denji/configuration_schema.json" - Not installed (using ,
npx,bunx,pnpx):yarn dlx"https://denji-docs.vercel.app/configuration_schema.json"
json
{
"$schema": "./node_modules/denji/configuration_schema.json",
"framework": "react",
"output": "./src/icons.tsx",
"typescript": true,
"a11y": "hidden",
"trackSource": true,
"allowedLibraries": ["lucide"],
"react": {
"forwardRef": true
},
"hooks": {
"postAdd": ["npx biome check --write ./src/icons.tsx"],
"postRemove": ["npx biome check --write ./src/icons.tsx"]
}
}Key fields:
| Field | Type | Description |
|---|---|---|
| string | Required. |
| string or object | Required. Path string or |
| boolean | Default: |
| string or false | |
| boolean | Default: |
| string[] | Restrict to specific Iconify prefixes. Empty/omitted = all allowed |
| object | Lifecycle hooks (see below) |
$schema- 本地安装():
npm i -D denji"./node_modules/denji/configuration_schema.json" - 未安装(使用,
npx,bunx,pnpx):yarn dlx"https://denji-docs.vercel.app/configuration_schema.json"
json
{
"$schema": "./node_modules/denji/configuration_schema.json",
"framework": "react",
"output": "./src/icons.tsx",
"typescript": true,
"a11y": "hidden",
"trackSource": true,
"allowedLibraries": ["lucide"],
"react": {
"forwardRef": true
},
"hooks": {
"postAdd": ["npx biome check --write ./src/icons.tsx"],
"postRemove": ["npx biome check --write ./src/icons.tsx"]
}
}关键字段:
| 字段 | 类型 | 描述 |
|---|---|---|
| 字符串 | 必填项。可选值: |
| 字符串或对象 | 必填项。路径字符串或 |
| 布尔值 | 默认值: |
| 字符串或false | 可选值: |
| 布尔值 | 默认值: |
| 字符串数组 | 限制为特定的Iconify前缀。为空/省略则允许所有前缀 |
| 对象 | 生命周期钩子(见下文) |
Output Modes
输出模式
File mode (default for React, Preact, Solid, Qwik, Vue): All icons in one file.
json
{ "output": "./src/icons.tsx" }Folder mode (required for Svelte, optional for others): One file per icon + barrel export.
json
{ "output": { "type": "folder", "path": "./src/icons" } }文件模式(React、Preact、Solid、Qwik、Vue的默认模式):所有图标放在一个文件中。
json
{ "output": "./src/icons.tsx" }文件夹模式(Svelte必填,其他框架可选):每个图标对应一个文件 + 桶导出文件。
json
{ "output": { "type": "folder", "path": "./src/icons" } }Hooks
钩子
Run shell commands at lifecycle points:
json
{
"hooks": {
"preAdd": ["echo 'Adding icons...'"],
"postAdd": ["npx prettier --write ./src/icons.tsx"],
"preRemove": [],
"postRemove": [],
"preClear": [],
"postClear": [],
"preList": [],
"postList": []
}
}在生命周期节点执行Shell命令:
json
{
"hooks": {
"preAdd": ["echo 'Adding icons...'"],
"postAdd": ["npx prettier --write ./src/icons.tsx"],
"preRemove": [],
"postRemove": [],
"preClear": [],
"postClear": [],
"preList": [],
"postList": []
}
}Common Patterns
常见模式
Dynamic Icons
动态图标
tsx
import { Icons, type IconName, type IconProps } from "./icons";
function DynamicIcon({ name, ...props }: { name: IconName } & IconProps) {
const Icon = Icons[name];
return <Icon {...props} />;
}
<DynamicIcon name="Check" className="size-4" />tsx
import { Icons, type IconName, type IconProps } from "./icons";
function DynamicIcon({ name, ...props }: { name: IconName } & IconProps) {
const Icon = Icons[name];
return <Icon {...props} />;
}
<DynamicIcon name="Check" className="size-4" />Accessibility
无障碍支持
tsx
// Decorative icon (hidden from screen readers)
<button>
<Icons.Check aria-hidden="true" />
Save
</button>
// Semantic icon (announced by screen readers)
<Icons.Check role="img" aria-label="Success" />
// Icon-only button
<button aria-label="Close">
<Icons.X aria-hidden="true" />
</button>tsx
// 装饰性图标(对屏幕阅读器隐藏)
<button>
<Icons.Check aria-hidden="true" />
保存
</button>
// 语义化图标(会被屏幕阅读器朗读)
<Icons.Check role="img" aria-label="成功" />
// 仅含图标的按钮
<button aria-label="关闭">
<Icons.X aria-hidden="true" />
</button>Restricting Icon Sources
限制图标来源
json
{
"allowedLibraries": ["lucide"]
}bash
npx denji add lucide:check # ✓ allowed
npx denji add mdi:home # ✗ Error: Icon "mdi:home" is not allowed. Allowed libraries: lucidejson
{
"allowedLibraries": ["lucide"]
}bash
npx denji add lucide:check # ✓ 允许
npx denji add mdi:home # ✗ 错误:图标“mdi:home”不被允许。允许的库:lucideFormatting with Hooks
使用钩子格式化代码
json
{
"hooks": {
"postAdd": ["npx biome check --write ./src/icons.tsx"],
"postRemove": ["npx biome check --write ./src/icons.tsx"]
}
}json
{
"hooks": {
"postAdd": ["npx biome check --write ./src/icons.tsx"],
"postRemove": ["npx biome check --write ./src/icons.tsx"]
}
}Using forwardRef (React/Preact)
使用forwardRef(React/Preact)
json
{
"framework": "react",
"react": { "forwardRef": true }
}tsx
const ref = useRef<SVGSVGElement>(null);
<Icons.Check ref={ref} className="size-4" />json
{
"framework": "react",
"react": { "forwardRef": true }
}tsx
const ref = useRef<SVGSVGElement>(null);
<Icons.Check ref={ref} className="size-4" />Framework Quick Reference
框架速查表
| Framework | Extensions | Default Output | Config Key | Notes |
|---|---|---|---|---|
| React | | file | | |
| Preact | | file | | |
| Solid | | file | | Refs work natively as props |
| Qwik | | file | | Uses |
| Vue | | file | | Uses |
| Svelte | | folder (only) | | Svelte 5 |
| 框架 | 扩展名 | 默认输出方式 | 配置键 | 说明 |
|---|---|---|---|---|
| React | | 文件 | | 支持 |
| Preact | | 文件 | | 通过 |
| Solid | | 文件 | | Refs原生作为props工作 |
| Qwik | | 文件 | | 在文件夹模式下使用 |
| Vue | | 文件 | | 使用 |
| Svelte | | 文件夹(仅支持此方式) | | 支持Svelte 5的 |
Deep-Dive References
深度参考
| Reference | Content |
|---|---|
| references/configuration.md | Full config schema, all framework options, output normalization |
| references/framework-patterns.md | Per-framework code examples, file vs folder imports, TypeScript types |
| 参考文档 | 内容 |
|---|---|
| references/configuration.md | 完整配置 schema、所有框架选项、输出规范化说明 |
| references/framework-patterns.md | 各框架代码示例、文件/文件夹导入方式、TypeScript类型说明 |