Generate reusable icon components for Prisma PHP and Caspian projects from the terminal.
ppicons downloads icon definitions from the remote catalog, normalizes the SVG, writes framework-native component files, and refreshes project metadata that documents the installed icon set.
The current component contract is HTML-first usage with x- tags:
<x-search /> <x-arrow-right class="size-4" />- Generates PHP icon components for Prisma PHP projects.
- Generates Python icon components for Caspian projects.
- Supports single-icon installs, multi-icon installs, and full-catalog generation.
- Updates already-installed icons by reading the generated component filenames.
- Refreshes
ppicons.json,.github/instructions/ppicons.instructions.md, andAGENTS.mdafter successful add or update runs. - Keeps generated icon usage aligned with HTML-first
x-tag output.
- Node.js 18+
- Network access to
https://ppicons.tsnc.tech - A target project with either
prisma-php.jsonorcaspian.config.jsonwhen using auto-detection
Global install:
npm install -g ppiconsLocal dev dependency:
npm install -D ppiconsUsage:
ppicons <command> [--all] [--lang py|php] [--force] [icon...]Commands:
addinstalls one or more new icons.updaterefreshes icons already present in the default generated directory.
Examples:
npx ppicons add search
npx ppicons add search user settings
npx ppicons add --all
npx ppicons add search --force
npx ppicons update| Flag | Description |
|---|---|
--all |
Generate every icon available from the catalog. |
--force |
Overwrite existing generated files. |
--lang php |
Force Prisma PHP output. |
--lang py |
Force Caspian Python output. |
If --lang is not passed, ppicons resolves the output mode from the current project root:
- If
caspian.config.jsonexists, it uses Python mode. - Else if
prisma-php.jsonexists, it uses PHP mode. - Else it falls back to PHP mode.
Examples:
npx ppicons add search --lang php
npx ppicons add search --lang pyppicons writes generated icons into the src tree of the current project.
| Mode | Output directory | File pattern |
|---|---|---|
| Prisma PHP | src/Lib/PPIcons |
src/Lib/PPIcons/<ComponentName>.php |
| Caspian | src/lib/ppicons |
src/lib/ppicons/<ComponentName>.py |
Component file names are PascalCase, while runtime usage stays kebab-case with the x- prefix.
Examples:
searchbecomesSearch.phporSearch.pyarrow-rightbecomesArrowRight.phporArrowRight.py- usage becomes
<x-search />or<x-arrow-right />
Generated icons are consumed as HTML-first x- components.
Import the generated classes into the PHP file, then render the icon with the x- tag.
<?php
use Lib\PPIcons\Search;
use Lib\PPIcons\ArrowRight;
?>
<x-search />
<x-arrow-right class="size-4" />When multiple icons come from the same generated namespace, grouped imports are preferred:
<?php
use Lib\PPIcons\{ArrowRight, Mail, UserRound};
?>
<div>
<x-mail class="size-4" />
<x-user-round class="size-4" />
<x-arrow-right class="size-4" />
</div>Import generated components from the Python module that authors their x- tags. Caspian has no HTML-sidecar or comment import syntax.
from casp.component_decorator import component, html
from src.lib.ppicons import ArrowRight, Search
@component
def icon_actions():
return html(r"""
<div>
<x-search />
<x-arrow-right class="size-4" />
</div>
""")Use html(r"""...""") for inline markup in the owning Python component, route, or layout.
Every successful add or update refreshes two project files.
This is the machine-readable manifest for the installed icon set. It includes:
schemaVersion: 7- detected project type, framework, language, and config file
- generated component and icon directories
- canonical command strings for add/update workflows
- remote catalog API metadata
- usage metadata for the current target
- the installed icon inventory
Example:
{
"schemaVersion": 7,
"generatedAt": "2026-04-28T00:00:00.000Z",
"project": {
"type": "prisma-php",
"framework": "prisma-php",
"language": "php",
"detectedBy": "prisma-php.json",
"rootDirectory": ".",
"sourceDirectory": "src",
"configFile": "prisma-php.json",
"manifestFile": "ppicons.json",
"componentsDirectory": "src/Lib/PPIcons",
"iconsDirectory": "src/Lib/PPIcons",
"copilotInstructionsFile": ".github/instructions/ppicons.instructions.md",
"agentsFile": "AGENTS.md"
},
"commands": {
"addOne": "npx ppicons add <icon-name>",
"addMany": "npx ppicons add <icon-a> <icon-b>",
"addAll": "npx ppicons add --all",
"updateInstalled": "npx ppicons update"
},
"usage": {
"componentType": "class",
"entryStyle": "namespace",
"entry": "Lib\\PPIcons",
"filePattern": "src/Lib/PPIcons/<ComponentName>.php",
"syntax": "jsx-like component tags"
},
"icons": [
{
"name": "search",
"componentName": "Search",
"file": "src/Lib/PPIcons/Search.php"
}
]
}This is the generated Copilot instruction file for projects using ppicons. It includes:
- the icons directory, generated file pattern, and import entry
- how to check whether an icon exists:
ppicons.jsoninventory, the icons directory, then the catalog API - install commands for missing icons
- project-specific usage examples with HTML-first
x-tags
The guidance is intentionally stable: it points agents at ppicons.json and the icons directory instead of listing installed icons, so adding or updating icons only changes ppicons.json. The file is rewritten only when the generated guidance itself changes.
ppicons also writes the same managed AI context to AGENTS.md for agents that discover repository guidance there. It preserves any user-authored content outside the <!-- ppicons:start --> and <!-- ppicons:end --> block.
The CLI reads icon data from the remote catalog.
Fetch all icons:
GET https://ppicons.tsnc.tech/icons?icon=all
Fetch one icon:
GET https://ppicons.tsnc.tech/icons?icon=search
Single icon response shape:
{
"id": 166531,
"name": "search",
"componentName": "Search",
"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"lucide lucide-search\"><circle cx=\"11\" cy=\"11\" r=\"8\"/><path d=\"m21 21-4.3-4.3\"/></svg>",
"createdAt": 1774923647142,
"updatedAt": 1774923647142
}Force PHP output explicitly:
npx ppicons add search --lang phpUse --force:
npx ppicons add search --forceThis means the target icon directory exists but no generated files for the current language mode were found yet.
Run an add command first:
npx ppicons add searchCheck the following:
- internet access is available
- your firewall or proxy allows requests to
https://ppicons.tsnc.tech - the icon name exists in the remote catalog
If you change generator behavior, keep the generated contract aligned across the repo.
- update the generator source in
src/ - update the matching tests in
tests/ - update this README when CLI behavior, output paths, or usage examples change
- update committed
dist/output so the published package matches the documented generator behavior
Released under the MIT License.
The Steel Ninja Code
thesteelninjacode@gmail.com