denji

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Managing 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
undefined
bash
undefined

1. 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 init

Initialize a Denji project. Creates
denji.json
config and icons template.
bash
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
FlagDescription
--framework <name>
react
,
preact
,
solid
,
qwik
,
vue
,
svelte
--output <path>
Output path for icons file/folder
--output-type <type>
file
(single file) or
folder
(one file per icon)
--typescript
/
--no-typescript
TypeScript or JavaScript (default: TS)
--a11y <strategy>
hidden
,
img
,
title
,
presentation
, or
false
(no a11y attrs)
--forward-ref
/
--no-forward-ref
Use forwardRef (React/Preact only)
--track-source
/
--no-track-source
Track Iconify source via
data-icon
attr
-c, --cwd <path>
Working directory
Missing flags trigger interactive prompts.
初始化Denji项目。创建
denji.json
配置文件和图标模板。
bash
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
标志描述
--framework <name>
可选值:
react
,
preact
,
solid
,
qwik
,
vue
,
svelte
--output <path>
图标文件/文件夹的输出路径
--output-type <type>
可选值:
file
(单个文件)或
folder
(每个图标对应一个文件)
--typescript
/
--no-typescript
使用TypeScript或JavaScript(默认:TS)
--a11y <strategy>
可选值:
hidden
,
img
,
title
,
presentation
,或
false
(不添加无障碍属性)
--forward-ref
/
--no-forward-ref
使用forwardRef(仅适用于React/Preact)
--track-source
/
--no-track-source
通过
data-icon
属性跟踪Iconify源
-c, --cwd <path>
工作目录
缺失的标志会触发交互式提示。

denji add <icons...>

denji add <icons...>

Add icons from Iconify. Icons use
prefix:name
format.
bash
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:name
格式。
bash
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

Preview 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
undefined
npx 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个图标,未写入任何文件
undefined

denji remove <icons...>

denji remove <icons...>

Remove icons by component name. Aliases:
rm
,
delete
,
del
.
bash
npx denji remove Check
npx denji rm Check Home ArrowRight
FlagDescription
-c, --cwd <path>
Working directory
按组件名称删除图标。别名:
rm
,
delete
,
del
bash
npx denji remove Check
npx denji rm Check Home ArrowRight
标志描述
-c, --cwd <path>
工作目录

denji list

denji list

List all icons in your project.
bash
npx denji list
npx denji list --display json
npx denji list --display toon
FlagDescription
--display <mode>
Output mode:
default
(human-readable),
json
, or
toon
-c, --cwd <path>
Working directory
Shows component names and Iconify source (if
trackSource: true
).
Default output:
Found 3 icon(s) in ./src/icons.tsx

Icons:
  • Check (lucide:check)
  • HomeOutline (mdi:home-outline)
  • ArrowRight (lucide:arrow-right)
JSON output (
--display json
):
json
{
  "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 (
--display toon
) uses TOON format for machine-readable binary encoding.
列出项目中的所有图标。
bash
npx denji list
npx denji list --display json
npx denji list --display toon
标志描述
--display <mode>
输出模式:
default
(人类可读格式)、
json
toon
-c, --cwd <path>
工作目录
显示组件名称和Iconify源(当
trackSource: true
时)。
默认输出:
在 ./src/icons.tsx 中找到3个图标

图标列表:
  • Check (lucide:check)
  • HomeOutline (mdi:home-outline)
  • ArrowRight (lucide:arrow-right)
JSON输出(
--display json
):
json
{
  "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输出(
--display toon
)使用TOON格式进行机器可读的二进制编码。

denji export

denji export

Export 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
FlagDescription
--output [path]
Write to file (default:
denji-export.json
if no path given)
-c, --cwd <path>
Working directory
Output format:
json
{
  "version": 1,
  "framework": "react",
  "output": "./src/icons.tsx",
  "icons": [
    { "name": "Home", "source": "mdi:home" },
    { "name": "Check", "source": "lucide:check" }
  ]
}
source
is included only when
trackSource: true
(the default).
导出所有已跟踪图标的JSON清单。
bash
npx denji export                    # 打印到标准输出
npx denji export --output icons.json
npx denji export --output           # 写入到 denji-export.json
标志描述
--output [path]
写入到文件(如果未指定路径,默认写入
denji-export.json
-c, --cwd <path>
工作目录
输出格式:
json
{
  "version": 1,
  "framework": "react",
  "output": "./src/icons.tsx",
  "icons": [
    { "name": "Home", "source": "mdi:home" },
    { "name": "Check", "source": "lucide:check" }
  ]
}
仅当
trackSource: true
(默认值)时才会包含
source
字段。

denji import

denji import

Bulk-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
FlagDescription
--dry-run
Preview without writing files
-c, --cwd <path>
Working directory
Icons without
prefix:name
format are skipped with a warning. JSON manifest entries without a
source
field are also skipped.
从清单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
标志描述
--dry-run
预览操作而不写入文件
-c, --cwd <path>
工作目录
不符合
prefix:name
格式的图标会被跳过并发出警告。JSON清单中没有
source
字段的条目也会被跳过。

denji clear

denji clear

Remove all icons. Aliases:
clr
,
reset
.
bash
npx denji clear
npx denji clear --yes
FlagDescription
-y, --yes
Skip confirmation prompt
-c, --cwd <path>
Working directory
删除所有图标。别名:
clr
,
reset
bash
npx denji clear
npx denji clear --yes
标志描述
-y, --yes
跳过确认提示
-c, --cwd <path>
工作目录

Config (
denji.json
)

配置文件(
denji.json

The
$schema
field depends on how Denji is installed:
  • 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:
FieldTypeDescription
framework
stringRequired.
react
,
preact
,
solid
,
qwik
,
vue
,
svelte
output
string or objectRequired. Path string or
{ type: "file"|"folder", path: "..." }
typescript
booleanDefault:
true
a11y
string or false
hidden
,
img
,
title
,
presentation
,
false
trackSource
booleanDefault:
true
. Adds
data-icon
attr
allowedLibraries
string[]Restrict to specific Iconify prefixes. Empty/omitted = all allowed
hooks
objectLifecycle hooks (see below)
$schema
字段取决于Denji的安装方式:
  • 本地安装
    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"]
  }
}
关键字段:
字段类型描述
framework
字符串必填项。可选值:
react
,
preact
,
solid
,
qwik
,
vue
,
svelte
output
字符串或对象必填项。路径字符串或
{ type: "file"|"folder", path: "..." }
typescript
布尔值默认值:
true
a11y
字符串或false可选值:
hidden
,
img
,
title
,
presentation
,
false
trackSource
布尔值默认值:
true
。添加
data-icon
属性
allowedLibraries
字符串数组限制为特定的Iconify前缀。为空/省略则允许所有前缀
hooks
对象生命周期钩子(见下文)

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: lucide
json
{
  "allowedLibraries": ["lucide"]
}
bash
npx denji add lucide:check   # ✓ 允许
npx denji add mdi:home       # ✗ 错误:图标“mdi:home”不被允许。允许的库:lucide

Formatting 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

框架速查表

FrameworkExtensionsDefault OutputConfig KeyNotes
React
.tsx
/
.jsx
file
react
forwardRef
option
Preact
.tsx
/
.jsx
file
preact
forwardRef
option (via
preact/compat
)
Solid
.tsx
/
.jsx
file
solid
Refs work natively as props
Qwik
.tsx
/
.jsx
file
qwik
Uses
component$()
in folder mode
Vue
.ts
/
.js
file
vue
Uses
h()
render functions
Svelte
.svelte
folder (only)
svelte
Svelte 5
$props()
runes
框架扩展名默认输出方式配置键说明
React
.tsx
/
.jsx
文件
react
支持
forwardRef
选项
Preact
.tsx
/
.jsx
文件
preact
通过
preact/compat
支持
forwardRef
选项
Solid
.tsx
/
.jsx
文件
solid
Refs原生作为props工作
Qwik
.tsx
/
.jsx
文件
qwik
在文件夹模式下使用
component$()
Vue
.ts
/
.js
文件
vue
使用
h()
渲染函数
Svelte
.svelte
文件夹(仅支持此方式)
svelte
支持Svelte 5的
$props()
runes

Deep-Dive References

深度参考

ReferenceContent
references/configuration.mdFull config schema, all framework options, output normalization
references/framework-patterns.mdPer-framework code examples, file vs folder imports, TypeScript types
参考文档内容
references/configuration.md完整配置 schema、所有框架选项、输出规范化说明
references/framework-patterns.md各框架代码示例、文件/文件夹导入方式、TypeScript类型说明