-
Notifications
You must be signed in to change notification settings - Fork 1
Open
Description
Problem
The iconify/json dependency is ~690MB because it bundles all icon sets. Most projects only use 10-100 icons, making this extremely wasteful.
// Current dependencies
"iconify/json": "^2.2", // ~690MB
"iconify/json-tools": "^1.0"Proposed Solution
Replace runtime icon lookup with a build-time approach:
- Scan templates for
meta_icon()calls duringcomposer install/update - Fetch only used icons from the Iconify API
- Save them locally as SVG files
- Read from local files at runtime
How It Would Work
composer install
↓
┌─────────────────────────────────────┐
│ studiometa/ui Composer Plugin │
│ │
│ 1. Scan templates for meta_icon() │
│ 2. Extract icon references │
│ 3. Diff with existing icons │
│ 4. Fetch new icons from API │
│ 5. Save SVGs to assets/icons/ │
└─────────────────────────────────────┘
↓
assets/icons/
├── mdi/
│ ├── home.svg
│ └── arrow-right.svg
└── heroicons/
└── chevron-down.svg
Size Comparison
| Approach | Vendor Size | Example (50 icons) |
|---|---|---|
iconify/json |
690MB | 690MB |
| Build-time fetching | ~5KB plugin | ~250KB |
Implementation
1. Change package type to composer-plugin
{
"type": "composer-plugin",
"require": {
"php": "^8.1",
"composer-plugin-api": "^2.0",
"studiometa/twig-toolkit": "^2.1.1",
"twig/twig": "^3.19.0"
},
"extra": {
"class": "Studiometa\\Ui\\Composer\\Plugin"
}
}2. Add Composer plugin classes
packages/
└── composer-plugin/
├── Plugin.php # Hooks into post-install/post-update
├── Config.php # Reads from composer.json extra
├── IconScanner.php # Scans templates for meta_icon() calls
├── IconFetcher.php # Fetches from Iconify API in batches
└── IconStorage.php # Saves/manages local SVG files
3. Modify meta_icon() to read local files
public function run(Environment $env, string $icon): string
{
[$prefix, $name] = explode(:, $icon);
// Try local file first
$localPath = sprintf(%s/%s/%s.svg, $this->iconPath, $prefix, $name);
if (file_exists($localPath)) {
return file_get_contents($localPath);
}
// Fallback: try iconify/json if installed (backward compat)
if (class_exists(\Iconify\JSONTools\Collection::class)) {
return $this->fromIconifyJson($prefix, $name, $env);
}
return $env->isDebug()
? "<!-- Icon '$prefix:$name' not found. Run 'composer ui:icons' -->"
: "";
}4. Configuration via composer.json
{
"extra": {
"studiometa/ui": {
"icons": {
"enabled": true,
"output": "assets/icons",
"scan": ["templates", "app"],
"include": ["mdi:loading"],
"exclude": ["mdi:test-*"]
}
}
}
}5. CLI commands
composer ui:icons # Sync icons (runs automatically)
composer ui:icons:scan # Show detected icons (dry-run)
composer ui:icons:prune # Remove unused iconsBenefits
- ~99% smaller - Only download icons you use
- No runtime network - Everything local after build
- Version controlled - Icons committed to git
- Automatic sync - Runs on composer install/update
- CI-friendly - Catch missing icons in pipeline
- Backward compatible - Still works with
iconify/jsonif installed
Backward Compatibility
Users who prefer the old approach can still require iconify/json:
{
"require": {
"studiometa/ui": "^2.0",
"iconify/json": "^2.2",
"iconify/json-tools": "^1.0"
},
"extra": {
"studiometa/ui": {
"icons": { "enabled": false }
}
}
}The meta_icon() function auto-detects and uses iconify/json if installed.
Context
This came up while evaluating studiometa/ui integration for the Foehn WordPress framework. The 690MB dependency is the main blocker for including it as a suggested/default package.
Happy to help implement this if there's interest!
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels