mathiasreker / php-svg-optimizer
php-svg-optimizer is a PHP library designed to optimize SVG files by applying various transformations and cleanup operations.
Installs: 8 099
Dependents: 1
Suggesters: 0
Security: 0
Stars: 29
Watchers: 1
Forks: 7
Open Issues: 0
pkg:composer/mathiasreker/php-svg-optimizer
Requires
- php: ^8.3
- ext-dom: *
- ext-libxml: *
- ext-mbstring: *
Requires (Dev)
- brainbits/phpstan-rules: ^4.0
- ergebnis/composer-normalize: ^2.49
- ergebnis/phpstan-rules: ^2.13
- friendsofphp/php-cs-fixer: ^3.93
- hiperdk/phpstan-rules: ^1.0
- kubawerlos/php-cs-fixer-custom-fixers: ^3.35
- marc-mabe/php-enum-phpstan: ^3.0
- odan/phpstan-rules: ^0.2
- phpstan/extension-installer: ^1.4
- phpstan/phpstan: ^2.1
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-mockery: ^2.0
- phpstan/phpstan-phpunit: ^2.0
- phpstan/phpstan-strict-rules: ^2.0
- phpunit/php-code-coverage: ^12.5
- phpunit/phpunit: ^12.5
- povils/phpmnd: ^3.6
- rector/rector: ^2.3
- shipmonk/composer-dependency-analyser: ^1.8
- shipmonk/phpstan-rules: ^4.3
- spaze/phpstan-disallowed-calls: ^4.7
- squizlabs/php_codesniffer: ^4.0
- symfony/var-dumper: ^7.4
- symplify/phpstan-rules: 14.9
- tomasvotruba/cognitive-complexity: ^1.0
- tomasvotruba/type-coverage: ^2.1
- voku/phpstan-rules: ^3.6
- dev-develop
- 8.2.6
- 8.2.5
- 8.2.4
- 8.2.3
- 8.2.2
- 8.2.1
- 8.2.0
- 8.1.0
- 8.0.3
- 8.0.2
- 8.0.1
- 8.0
- 7.3.0
- 7.2.0
- 7.1.4
- 7.1.3
- 7.1.2
- 7.1.1
- 7.1.0
- 7.0.4
- 7.0.3
- 7.0.2
- 7.0.1
- 7.0.0
- 6.0.4
- 6.0.3
- 6.0.2
- 6.0.1
- 6.0.0
- 5.3.5
- 5.3.4
- 5.3.3
- 5.3.1
- 5.3.0
- 5.2.8
- 5.2.7
- 5.2.6
- 5.2.5
- 5.2.4
- 5.2.3
- 5.2.2
- 5.2.1
- 5.2.0
- 5.1.2
- 5.1.1
- 5.1.0
- 5.0.3
- 5.0.2
- 5.0.1
- 5.0.0
- 4.1.0
- 4.0.5
- 4.0.3
- 4.0.2
- 4.0.0
- 3.0.5
- 3.0.4
- 3.0.3
- 3.0.2
- 3.0.1
- 3.0.0
- 2.0.1
- 2.0.0
- 1.0.5
- 1.0.4
- 1.0.3
- 1.0.2
- 1.0.0
- dev-dependabot/composer/phpstan/phpstan-2.1.38
This package is auto-updated.
Last update: 2026-02-01 20:32:19 UTC
README
php-svg-optimizer is a lightweight PHP library designed to optimize, minify, and sanitize SVG files.
It applies various transformations and cleanup operations while ensuring compliance with SVG 2.0 specifications.
The resulting SVGs remain visually identical to the original but are smaller, cleaner, and safer.
Versions & Dependencies
| Version | PHP | Documentation |
|---|---|---|
| ^8.3 | ^8.3 | current |
Requirements
ext-dom: Required PHP extension for XML handling.ext-libxml: Required PHP extension for XML error handling.ext-mbstring: Required PHP extension for multibyte string handling.
Installation
To install the library, run:
composer require mathiasreker/php-svg-optimizer
Using the Library
You can use this library in two main ways:
-
Command-Line Interface (CLI): Run the optimizer directly from your terminal to process SVG files quickly. This is ideal for batch processing or integrating into build scripts.
-
Standalone Package: Use it as a PHP package in your project to optimize SVGs programmatically. This allows you to integrate SVG optimization directly into your application workflow or custom scripts.
CLI tool
vendor/bin/svg-optimizer [options] process <path1> <path2> ...
Options: -h , --help Display help for the command. -c , --config Path to a JSON file with custom optimization rules. If not provided, all default optimizations will be applied. -d , --dry-run Only calculate potential savings without modifying the files. -r , --allow-risky Explicitly enables risky rules, allowing them to be applied. -a , --with-all-rules Enable all non-risky rules. Use --allow-risky to include risky rules as well. -q , --quiet Suppress all output except errors. -v , --version Display the version of the library. Commands: Process Provide a list of directories or files to process.
Examples:
vendor/bin/svg-optimizer --dry-run --with--all-rules process /path/to/svgs
vendor/bin/svg-optimizer --config=config.json process /path/to/file.svg
vendor/bin/svg-optimizer --config='{"removeUnsafeElements": true}' --allow-risky process /path/to/file.svg
vendor/bin/svg-optimizer --quiet --with--all-rules process /path/to/file.svg
vendor/bin/svg-optimizer --with-all-rules process /path/to/file.svg
Config file example:
{
"convertColorsToHex": true,
"convertCssClassesToAttributes": true,
"convertEmptyTagsToSelfClosing": true,
"convertInlineStylesToAttributes": true,
"fixAttributeNames": true,
"flattenGroups": true,
"minifySvgCoordinates": true,
"minifyTransformations": true,
"removeAriaAndRole": true,
"removeComments": true,
"removeDataAttributes": true,
"removeDefaultAttributes": true,
"removeDeprecatedAttributes": true,
"removeDoctype": true,
"removeDuplicateElements": true,
"removeEmptyAttributes": true,
"removeEmptyGroups": true,
"removeEmptyTextElements": true,
"removeEnableBackgroundAttribute": true,
"removeInkscapeFootprints": true,
"removeInvisibleCharacters": true,
"removeMetadata": true,
"removeTitleAndDesc": true,
"removeUnnecessaryWhitespace": true,
"removeUnsafeElements": false,
"removeUnusedMasks": true,
"removeUnusedNamespaces": true,
"removeWidthHeightAttributes": false,
"sortAttributes": true
}
Example Workflow for GitHub Actions
name: Optimize SVGs
on: [push, pull_request]
jobs:
run-optimizer:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: shivammathur/setup-php@v2
with:
php-version: '8.5'
- run: composer install --no-dev --optimize-autoloader --no-interaction --no-progress
- run: php vendor/bin/svg-optimizer -a -q process /path/to/svgs
Package
It is recommended to catch exceptions when using this library. Doing so ensures that your application can handle unexpected input gracefully and avoid unintended crashes.
Example specifying rules
<?php declare(strict_types=1); require_once __DIR__ . '/vendor/autoload.php'; use MathiasReker\PhpSvgOptimizer\Service\Facade\SvgOptimizerFacade; try { $svgOptimizer = SvgOptimizerFacade::fromFile('path/to/source.svg') ->withRules( convertColorsToHex: true, convertCssClassesToAttributes: true, convertEmptyTagsToSelfClosing: true, convertInlineStylesToAttributes: true, fixAttributeNames: true, flattenGroups: true, minifySvgCoordinates: true, minifyTransformations: true, removeAriaAndRole: true, removeComments: true, removeDataAttributes: true, removeDefaultAttributes: true, removeDeprecatedAttributes: true, removeDoctype: true, removeDuplicateElements: true, removeEmptyAttributes: true, removeEmptyGroups: true, removeEmptyTextElements: true, removeEnableBackgroundAttribute: true, removeInkscapeFootprints: true, removeInvisibleCharacters: true, removeMetadata: true, removeTitleAndDesc: true, removeUnnecessaryWhitespace: true, removeUnsafeElements: false, removeUnusedMasks: true, removeUnusedNamespaces: true, removeWidthHeightAttributes: false, sortAttributes: true, ) ->optimize() ->saveToFile('path/to/output.svg'); } catch (\Exception $exception) { echo $exception->getMessage(); }
Example parsing from a file and saving to a file using default rules
<?php declare(strict_types=1); require_once __DIR__ . '/vendor/autoload.php'; use MathiasReker\PhpSvgOptimizer\Service\Facade\SvgOptimizerFacade; try { $svgOptimizer = SvgOptimizerFacade::fromFile('path/to/source.svg') ->withAllRules() ->optimize() ->saveToFile('path/to/output.svg'); $metaData = $svgOptimizer->getMetaData(); echo sprintf('Optimized size: %d bytes%s', $metaData->getOptimizedSize(), \PHP_EOL); echo sprintf('Original size: %d bytes%s', $metaData->getOriginalSize(), \PHP_EOL); echo sprintf('Size reduction: %d bytes%s', $metaData->getSavedBytes(), \PHP_EOL); echo sprintf('Reduction percentage: %s %%%s', $metaData->getSavedPercentage(), \PHP_EOL); echo sprintf('Processing time: %s seconds%s', $metaData->getOptimizationTime(), \PHP_EOL); } catch (\Exception $exception) { echo $exception->getMessage(); }
Example parsing from a file and returning the content using default rules
<?php declare(strict_types=1); require_once __DIR__ . '/vendor/autoload.php'; use MathiasReker\PhpSvgOptimizer\Service\Facade\SvgOptimizerFacade; try { $svgOptimizer = SvgOptimizerFacade::fromFile('path/to/source.svg') ->withAllRules() ->optimize(); echo sprintf('Get content: ', $svgOptimizer->getContent(), \PHP_EOL); $metaData = $svgOptimizer->getMetaData(); echo sprintf('Optimized size: %d bytes%s', $metaData->getOptimizedSize(), \PHP_EOL); echo sprintf('Original size: %d bytes%s', $metaData->getOriginalSize(), \PHP_EOL); echo sprintf('Size reduction: %d bytes%s', $metaData->getSavedBytes(), \PHP_EOL); echo sprintf('Reduction percentage: %s %%%s', $metaData->getSavedPercentage(), \PHP_EOL); echo sprintf('Processing time: %s seconds%s', $metaData->getOptimizationTime(), \PHP_EOL); } catch (\Exception $exception) { echo $exception->getMessage(); }
Example parsing from a string and returning the content using default rules
<?php declare(strict_types=1); require_once __DIR__ . '/vendor/autoload.php'; use MathiasReker\PhpSvgOptimizer\Service\Facade\SvgOptimizerFacade; try { $svgOptimizer = SvgOptimizerFacade::fromString('<svg>...</svg>') ->withAllRules() ->optimize(); echo sprintf('Content: ', $svgOptimizer->getContent(), \PHP_EOL); $metaData = $svgOptimizer->getMetaData(); echo sprintf('Optimized size: %d bytes%s', $metaData->getOptimizedSize(), \PHP_EOL); echo sprintf('Original size: %d bytes%s', $metaData->getOriginalSize(), \PHP_EOL); echo sprintf('Size reduction: %d bytes%s', $metaData->getSavedBytes(), \PHP_EOL); echo sprintf('Reduction percentage: %s %%%s', $metaData->getSavedPercentage(), \PHP_EOL); echo sprintf('Processing time: %s seconds%s', $metaData->getOptimizationTime(), \PHP_EOL); } catch (\Exception $exception) { echo $exception->getMessage(); }
Example applying risky rules
<?php declare(strict_types=1); require_once __DIR__ . '/vendor/autoload.php'; use MathiasReker\PhpSvgOptimizer\Service\Facade\SvgOptimizerFacade; try { $svgOptimizer = SvgOptimizerFacade::fromFile('path/to/source.svg') ->withRules( removeWidthHeightAttributes: true, removeUnsafeElements: true, ) ->allowRisky() ->optimize() ->saveToFile('path/to/output.svg'); echo sprintf('Content: ', $svgOptimizer->getContent(), \PHP_EOL); $metaData = $svgOptimizer->getMetaData(); echo sprintf('Optimized size: %d bytes%s', $metaData->getOptimizedSize(), \PHP_EOL); echo sprintf('Original size: %d bytes%s', $metaData->getOriginalSize(), \PHP_EOL); echo sprintf('Size reduction: %d bytes%s', $metaData->getSavedBytes(), \PHP_EOL); echo sprintf('Reduction percentage: %s %%%s', $metaData->getSavedPercentage(), \PHP_EOL); echo sprintf('Processing time: %s seconds%s', $metaData->getOptimizationTime(), \PHP_EOL); } catch (\Exception $exception) { echo $exception->getMessage(); }
Documentation
SvgOptimizerFacade
Static factory method to create SvgOptimizerFacade from a file path.
$svgOptimizer = SvgOptimizerFacade::fromFile('path/to/source.svg');
Static factory method to create SvgOptimizerFacade from a string.
$svgOptimizer = SvgOptimizerFacade::fromString('<svg>...</svg>');
withRules
Configure which SVG optimization rules to apply. The method accepts boolean parameters that determine whether specific rules should be enabled or disabled.
$svgOptimizer->withRules();
Parameters
Below is a detailed description of each available optimization rule. Each rule focuses on either reducing file size, improving consistency, modernizing SVG output, or increasing security. Some rules are marked risky, meaning they may alter behavior or semantics in certain use cases and should be enabled with care.
convertColorsToHex
Normalizes all color definitions to hexadecimal notation. Color values expressed as functional formats (such as rgb()
or rgba()) are converted to their hexadecimal equivalents, using shorthand notation where possible.
This improves consistency across the SVG, reduces textual variation, and can slightly decrease file size while
maintaining visual fidelity.
$svgOptimizer->convertColorsToHex();
convertCssClassesToAttributes
Replaces CSS class-based styling with equivalent inline SVG attributes on each affected element.
$svgOptimizer->convertCssClassesToAttributes();
convertEmptyTagsToSelfClosing
Converts elements without child nodes into self-closing tags. This simplifies the markup structure and reduces unnecessary characters, resulting in cleaner and more compact SVG output without affecting rendering.
$svgOptimizer->convertEmptyTagsToSelfClosing();
convertInlineStylesToAttributes
Extracts individual style declarations from inline style attributes and converts them into their corresponding SVG
presentation attributes. This improves compatibility with SVG renderers and tooling that do not fully support CSS
styling, and makes attribute-level optimizations more effective downstream.
$svgOptimizer->convertInlineStylesToAttributes();
fixAttributeNames (risky)
Normalizes SVG attribute names to their canonical, specification-compliant casing and hyphenation. Attribute names are matched against a known set of valid SVG attributes and corrected where case differences or missing hyphens occur. This improves standards compliance, avoids duplicate or conflicting attributes, and ensures consistent output across different SVG sources and editors.
$svgOptimizer->fixAttributeNames();
flattenGroups
Removes unnecessary nested <g> (group) elements by moving their child elements directly into the parent group. This
reduces DOM depth, simplifies the SVG structure, and can marginally reduce file size while preserving visual output.
$svgOptimizer->flattenGroups();
minifySvgCoordinates
Reduces numeric precision in coordinate values and other numeric attributes where excessive precision is unnecessary. Trailing zeros and redundant decimal places are removed without introducing visible rendering differences, leading to smaller file sizes and cleaner markup.
$svgOptimizer->minifySvgCoordinates();
minifyTransformations
Optimizes transform attributes by simplifying expressions, removing redundant transformations, and normalizing
transform syntax. This reduces attribute length and improves parsing efficiency while maintaining equivalent geometric
transformations.
$svgOptimizer->minifyTransformations();
removeAriaAndRole
Removes ARIA (aria-*) and role attributes that are often unnecessary in static or decorative SVGs. This reduces file
size and avoids redundant accessibility metadata when SVGs are not intended to be interactive or exposed to assistive
technologies.
$svgOptimizer->removeAriaAndRole();
removeComments
Deletes all non-essential XML comments from the SVG document, excluding legally required comments if applicable. This eliminates developer notes and editor artifacts that do not affect rendering, reducing file size.
$svgOptimizer->removeComments();
removeDataAttributes (risky)
Removes all data-* attributes from elements. These attributes are often used for application-specific metadata or
scripting hooks; removing them can significantly reduce file size but may break integrations or runtime behavior that
relies on them.
$svgOptimizer->removeDataAttributes();
removeDefaultAttributes
Eliminates attributes whose values match SVG specification defaults and therefore do not affect rendering. By omitting redundant information, this rule reduces clutter and minimizes output size while preserving visual correctness.
$svgOptimizer->removeDefaultAttributes();
removeDeprecatedAttributes
Removes attributes that are deprecated or obsolete according to modern SVG specifications. This helps modernize SVG output, improves forward compatibility, and reduces reliance on legacy behavior.
$svgOptimizer->removeDeprecatedAttributes();
removeDoctype
Removes the <!DOCTYPE> declaration from the SVG document. This is typically unnecessary for inline SVGs or SVGs
embedded in HTML and slightly reduces file size.
$svgOptimizer->removeDoctype();
removeDuplicateElements
Detects and removes identical duplicate elements that do not contribute additional visual output. This reduces redundancy in the SVG structure and helps minimize file size without altering appearance.
$svgOptimizer->removeDuplicateElements();
removeEmptyAttributes
Removes attributes that have empty values. Such attributes add noise to the markup without affecting rendering and can safely be removed to produce cleaner output.
$svgOptimizer->removeEmptyAttributes();
removeEmptyGroups
Deletes <g> elements that do not contain any child elements. This simplifies the DOM tree and removes unnecessary
structural nodes.
$svgOptimizer->removeEmptyGroups();
removeEmptyTextElements
Removes <text> elements that contain no textual content. These elements have no visual impact and can safely be
eliminated to reduce file size.
$svgOptimizer->removeEmptyTextElements();
removeEnableBackgroundAttribute (risky)
Removes the enable-background attribute from the root <svg> element. While often unnecessary, this attribute can
affect certain filters or compositing behaviors. Removing it may improve performance and reduce size but could alter
rendering in advanced use cases.
$svgOptimizer->removeEnableBackgroundAttribute();
removeInkscapeFootprints
Strips Inkscape-specific metadata, attributes, and elements that are added during export but are not required for rendering. This cleans up SVGs generated by Inkscape and significantly reduces noise and file size.
$svgOptimizer->removeInkscapeFootprints();
removeInvisibleCharacters
Removes invisible or non-printable Unicode characters, such as zero-width spaces, that may inadvertently appear in SVG files. This prevents subtle rendering or parsing issues and ensures clean textual content.
$svgOptimizer->removeInvisibleCharacters();
removeMetadata
Deletes <metadata> elements, which often contain authoring information, editor data, or descriptive metadata not
required for rendering. This reduces file size and removes non-essential content.
$svgOptimizer->removeMetadata();
removeTitleAndDesc
Removes <title> and <desc> elements. While these elements provide accessibility and descriptive information, they
are optional in many contexts. Removing them reduces file size but should only be done when accessibility metadata is
not required.
$svgOptimizer->removeTitleAndDesc();
removeUnnecessaryWhitespace
Collapses or removes redundant whitespace such as extra spaces, tabs, and line breaks. This produces more compact SVG output while preserving semantic structure and rendering.
$svgOptimizer->removeUnnecessaryWhitespace();
removeUnusedNamespaces
Removes XML namespace declarations that are never referenced within the document. This cleans up the root element, reduces verbosity, and improves readability.
$svgOptimizer->removeUnusedNamespaces();
removeWidthHeightAttributes (risky)
Removes the width and height attributes from the root <svg> element, relying solely on the viewBox for scaling.
This enables responsive resizing but may break layouts that depend on fixed dimensions.
$svgOptimizer->removeWidthHeightAttributes();
removeUnsafeElements (risky)
Sanitizes SVG content by removing elements and attributes that can pose security risks. This includes scripting capabilities, external resource references, and interactive event handlers. The rule is intended for use with untrusted SVG input and helps prevent script execution, data exfiltration, and other attack vectors when embedding SVGs in web applications.
$svgOptimizer->removeUnsafeElements();
removeUnusedMasks
Removes <mask> elements that are defined but never referenced by any element in the document. This reduces file size
and eliminates unused definitions without affecting rendering.
$svgOptimizer->removeUnusedMasks();
sortAttributes
Sorts element attributes alphabetically. This improves consistency, makes diffs easier to read in version control systems, and results in more deterministic SVG output across optimization runs.
$svgOptimizer->sortAttributes();
withRules
Below you see the default configuration. You can configure each rule individually by passing the desired values to it:
$svgOptimizer->withRules( convertColorsToHex: true, convertCssClassesToAttributes: true, convertEmptyTagsToSelfClosing: true, convertInlineStylesToAttributes: true, fixAttributeNames: true, flattenGroups: true, minifySvgCoordinates: true, minifyTransformations: true, removeAriaAndRole: true, removeComments: true, removeDefaultAttributes: true, removeDeprecatedAttributes: true, removeDoctype: true, removeDuplicateElements: true, removeEmptyAttributes: true, removeEmptyGroups: true, removeEmptyTextElements: true, removeEnableBackgroundAttribute: true, removeInkscapeFootprints: true, removeInvisibleCharacters: true, removeMetadata: true, removeTitleAndDesc: true, removeUnnecessaryWhitespace: true, removeUnsafeElements: false, removeUnusedMasks: true, removeUnusedNamespaces: true, removeWidthHeightAttributes: false, sortAttributes: true, );
withAllRules
Enable all rules. Risky rules remain disabled unless allowRisky() is explicitly set.
$svgOptimizer->withAllRules();
allowRisky
By default, risky rules are not applied even if you add them unless explicitly allowed.
$svgOptimizer->allowRisky();
optimize
Finalizes the optimization process and generates the optimized SVG file.
$svgOptimizer->optimize();
saveToFile
Saves the optimized SVG file to the specified path.
$svgOptimizer->saveToFile('path/to/output.svg');
getContent
Returns the optimized SVG content.
$svgOptimizer->getContent();
getOptimizedSize
Returns the size of the optimized SVG file.
$svgOptimizer->getMetaData()->getOptimizedSize();
getOriginalSize
Returns the size of the original SVG file.
$svgOptimizer->getMetaData()->getOriginalSize();
getSavedBytes
Returns the number of bytes saved by the optimization process.
$svgOptimizer->getMetaData()->getSavedBytes();
getSavedPercentage
Returns the percentage of bytes saved by the optimization process.
$svgOptimizer->getMetaData()->getSavedPercentage();
getOptimizedTime
Returns the time taken to optimize the SVG file, in seconds.
$svgOptimizer->getMetaData()->getOptimizedTime();
Roadmap
For a complete list of proposed features and known issues, see the open issues.
Contributing
We welcome all contributions! If you have ideas for improvements, feel free to fork the repository and submit a pull request. You can also open an issue. If you find this project helpful, don’t forget to give it a star!
Library Structure and Contribution Guide
The library implements the Strategy Pattern, where strategies are encapsulated as "rules" located in the
/src/Service/Rule directory.
Adding a New Rule
1. Create the Rule
Create a new final readonly class in the /src/Service/Rule directory and implement
the SvgOptimizerRuleInterface. This interface will define the logic for your rule.
2. Write Tests
Write comprehensive unit tests for your rule in the /tests/Unit/Service/Rule directory. Ensure the tests cover
various scenarios to verify the correct behavior and edge cases for your rule.
3. Integrate the Rule
- Add your rule to the rule enum in
/src/Type/Rule.php. - Register the rule in the SVG optimizer builder located at
/src/Service/Facade/SvgOptimizerFacade.php.
4. Update Documentation
Document the functionality and purpose of your rule in the README.md to ensure users understand its behavior and
usage.
Docker
To use the project with Docker, you can start the container using:
docker-compose up -d
Then, access the container:
docker exec -it php-svg-optimizer bash
Tools
Run static analysis:
composer analyze:all
Run tests:
composer test
Fix code style:
composer lint:all
Build:
composer build:all
License
This project is licensed under the MIT License. See the LICENSE file for more information.
Disclaimer
Use of this tool is entirely at your own risk. The authors and maintainers make no warranties regarding the correctness, reliability, or suitability of the tool for any particular purpose. Users are solely responsible for verifying the results and ensuring that files are properly backed up before use. It is strongly recommended to test the tool on non-critical files and confirm compatibility with your workflow prior to deploying it in any production environment.
