denji

Manage SVG icons as framework components using Denji CLI. Use when the user needs to add, remove, list, export, import, or manage SVG icons in React, Preact, Solid, Qwik, Vue, or Svelte projects. Triggers include requests to "add an icon", "set up icons", "manage SVG icons", "remove an icon", "list icons", "export icons", "import icons", "dry-run icon add", or any task involving Iconify icons as framework components.

7 stars

Best use case

denji is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Manage SVG icons as framework components using Denji CLI. Use when the user needs to add, remove, list, export, import, or manage SVG icons in React, Preact, Solid, Qwik, Vue, or Svelte projects. Triggers include requests to "add an icon", "set up icons", "manage SVG icons", "remove an icon", "list icons", "export icons", "import icons", "dry-run icon add", or any task involving Iconify icons as framework components.

Teams using denji should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/denji/SKILL.md --create-dirs "https://raw.githubusercontent.com/fellipeutaka/denji/main/skills/denji/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/denji/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How denji Compares

Feature / AgentdenjiStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Manage SVG icons as framework components using Denji CLI. Use when the user needs to add, remove, list, export, import, or manage SVG icons in React, Preact, Solid, Qwik, Vue, or Svelte projects. Triggers include requests to "add an icon", "set up icons", "manage SVG icons", "remove an icon", "list icons", "export icons", "import icons", "dry-run icon add", or any task involving Iconify icons as framework components.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# Managing SVG Icons with Denji

Denji converts Iconify SVG icons into typed framework components. Icons are fetched, optimized (SVGO), and generated as native components for your framework.

## Core Workflow

```bash
# 1. Initialize project
npx denji init --framework react --output ./src/icons.tsx

# 2. Add icons (prefix:name format from Iconify)
npx denji add lucide:check lucide:x lucide:arrow-right

# 3. Use in your code
```

```tsx
import { Icons } from "./icons";

<Icons.Check className="size-4 text-green-500" />
<Icons.X className="size-4 text-red-500" />
```

## Commands

### `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
```

| Flag | Description |
|------|-------------|
| `--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 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
# 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
```

### `denji remove <icons...>`

Remove icons by component name. Aliases: `rm`, `delete`, `del`.

```bash
npx denji remove Check
npx denji rm Check Home ArrowRight
```

| Flag | Description |
|------|-------------|
| `-c, --cwd <path>` | Working directory |

### `denji list`

List all icons in your project.

```bash
npx denji list
npx denji list --display json
npx denji list --display toon
```

| Flag | Description |
|------|-------------|
| `--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](https://github.com/toon-format/toon) for machine-readable binary encoding.

### `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
```

| Flag | Description |
|------|-------------|
| `--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).

### `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
```

| Flag | Description |
|------|-------------|
| `--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.

### `denji clear`

Remove all icons. Aliases: `clr`, `reset`.

```bash
npx denji clear
npx denji clear --yes
```

| Flag | Description |
|------|-------------|
| `-y, --yes` | Skip confirmation prompt |
| `-c, --cwd <path>` | Working directory |

## Config (`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:

| Field | Type | Description |
|-------|------|-------------|
| `framework` | string | Required. `react`, `preact`, `solid`, `qwik`, `vue`, `svelte` |
| `output` | string or object | Required. Path string or `{ type: "file"\|"folder", path: "..." }` |
| `typescript` | boolean | Default: `true` |
| `a11y` | string or false | `hidden`, `img`, `title`, `presentation`, `false` |
| `trackSource` | boolean | Default: `true`. Adds `data-icon` attr |
| `allowedLibraries` | string[] | Restrict to specific Iconify prefixes. Empty/omitted = all allowed |
| `hooks` | object | Lifecycle hooks (see below) |

### 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" } }
```

### 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": []
  }
}
```

## 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" />
```

### 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>
```

### 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
```

### Formatting with Hooks

```json
{
  "hooks": {
    "postAdd": ["npx biome check --write ./src/icons.tsx"],
    "postRemove": ["npx biome check --write ./src/icons.tsx"]
  }
}
```

### Using forwardRef (React/Preact)

```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 | `.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 |

## Deep-Dive References

| Reference | Content |
|-----------|---------|
| [references/configuration.md](references/configuration.md) | Full config schema, all framework options, output normalization |
| [references/framework-patterns.md](references/framework-patterns.md) | Per-framework code examples, file vs folder imports, TypeScript types |

Related Skills

solid

7
from fellipeutaka/denji

Apply SOLID principles to write flexible, maintainable, and testable code. Use when designing classes, interfaces, and module boundaries. Covers Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation, and Dependency Inversion with practical TypeScript examples and detection heuristics.

zod

7
from fellipeutaka/denji

Zod 4 — TypeScript-first schema validation with static type inference. Use when writing Zod schemas, validating data, defining types with Zod, parsing input, creating form validation schemas, defining API request/response schemas, working with z.object, z.string, z.number, z.enum, z.array, z.union, z.discriminatedUnion, z.file, z.jwt, z.email, z.uuid, z.url, z.codec, z.toJSONSchema, z.fromJSONSchema, z.int, z.stringbool, z.templateLiteral, z.record, z.partialRecord, or any other Zod API. Also use when migrating from Zod 3 to Zod 4, or when the user's package.json shows zod@^4. CRITICAL: Always use Zod 4 APIs. Never use deprecated Zod 3 patterns unless user explicitly requests Zod 3 compatibility.

web-design-guidelines

7
from fellipeutaka/denji

Review UI code for Web Interface Guidelines compliance. Use when asked to "review my UI", "check accessibility", "audit design", "review UX", or "check my site against best practices".

vercel-react-best-practices

7
from fellipeutaka/denji

React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.

vercel-composition-patterns

7
from fellipeutaka/denji

React composition patterns that scale. Use when refactoring components with boolean prop proliferation, building flexible component libraries, or designing reusable APIs. Triggers on tasks involving compound components, render props, context providers, or component architecture. Includes React 19 API changes.

turborepo

7
from fellipeutaka/denji

Turborepo monorepo build system guidance. Triggers on: turbo.json, task pipelines, dependsOn, caching, remote cache, the "turbo" CLI, --filter, --affected, CI optimization, environment variables, internal packages, monorepo structure/best practices, and boundaries. Use when user: configures tasks/workflows/pipelines, creates packages, sets up monorepo, shares code between apps, runs changed/affected packages, debugs cache, or has apps/packages directories.

tanstack-virtual

7
from fellipeutaka/denji

TanStack Virtual headless virtualization for React. Use when rendering large lists (100+ items), implementing virtual scroll, building infinite scroll feeds, virtualizing grids or tables, using window-level scrolling, or implementing masonry/lane layouts with @tanstack/react-virtual. Triggers on: useVirtualizer, useWindowVirtualizer, virtual list, virtual scroll, list virtualization.

tanstack-query

7
from fellipeutaka/denji

TanStack Query (React Query) v5 best practices for data fetching, caching, mutations, and server state management. Use when building data-driven React applications, setting up query configurations, implementing mutations/optimistic updates, configuring caching strategies, integrating with SSR, or fixing v4→v5 migration errors.

tanstack-pacer

7
from fellipeutaka/denji

TanStack Pacer best practices for execution control in React — debouncing, throttling, rate limiting, queuing, and batching. Use when implementing search inputs, scroll handlers, API rate limits, task queues, bulk operations, or any scenario requiring controlled execution timing with reactive state.

tanstack-hotkeys

7
from fellipeutaka/denji

Guide for implementing keyboard shortcuts in React using @tanstack/react-hotkeys. Use when building hotkey/shortcut features, registering keyboard shortcuts, handling key sequences, recording custom shortcuts, tracking held keys, or formatting hotkeys for display in React applications.

skill-creator

7
from fellipeutaka/denji

Guide for creating effective skills. This skill should be used when users want to create a new skill (or update an existing skill) that extends Claude's capabilities with specialized knowledge, workflows, or tool integrations.

seo-audit

7
from fellipeutaka/denji

When the user wants to audit, review, or diagnose SEO issues on their site. Also use when the user mentions "SEO audit," "technical SEO," "why am I not ranking," "SEO issues," "on-page SEO," "meta tags review," or "SEO health check." For building pages at scale to target keywords, see programmatic-seo. For adding structured data, see schema-markup.