DevTools
asset_optimizer Pro
- Tier
- Proversion 1.1.3
- Command
archipelago generate asset_optimizer- Generates
devtools/scripts/asset_optimizer
- Depends on
- monorepo_toolkitgenerate these first
Image asset optimization (SVG via
svgo, PNG viaoxipng, JPEG viajpegoptim). Adds anassetscommand to the basemonorepo_toolkitCLI.
What it is
A monorepo_toolkit sub-command that scans the workspace's asset directories and shrinks SVG/PNG/JPEG files in place using external CLI tools. Requires monorepo_toolkit to already be generated — this brick only adds a command onto it, it does not stand alone.
Variables
| Variable | Type | Default | Description |
|---|---|---|---|
| appName | string | MyApp | The name of your application |
| isForMonorepo | boolean | true | Whether this is being generated as part of a monorepo |
Usage
Interactive
archipelago generate asset_optimizerNon-interactive (CI)
archipelago generate asset_optimizer --config my_config.jsonRunning the command
dart run monorepo_toolkit assets optimize
dart run monorepo_toolkit assets optimize --dry-run
dart run monorepo_toolkit assets optimize --config custom_optimizer.yamlRequires the underlying tools to be installed: svgo (npm install -g svgo), oxipng (brew install oxipng or cargo install oxipng), jpegoptim (brew install jpegoptim or apt-get install jpegoptim). optimize checks for each enabled format's tool up front and refuses to run (prints install instructions) if any are missing.
Generated Structure
devtools/
└── scripts/
└── asset_optimizer/
├── example/
│ └── asset_optimizer.yaml # Reference config (correct schema)
├── lib/
│ ├── asset_optimizer.dart # Barrel export
│ └── src/
│ ├── commands/
│ │ ├── asset_optimize_command.dart # `assets` parent command
│ │ └── optimize_command.dart # `assets optimize` subcommand
│ ├── models/
│ │ └── asset_optimizer_config.dart # AssetOptimizerConfig + Svg/Png/JpegConfig
│ └── services/
│ ├── asset_optimizer_service.dart
│ └── optimizers/
│ ├── optimizer.dart # Optimizer contract
│ ├── svg_optimizer.dart # name: 'svgo'
│ ├── png_optimizer.dart # name: 'oxipng'
│ └── jpeg_optimizer.dart # name: 'jpegoptim'
└── pubspec.yamlConfig schema
asset_optimizer:
paths: # default: apps/*/assets, apps/*/*/assets, packages/*/assets
- apps/*/assets
svg:
enabled: true
# disable_plugins: [removeViewBox]
png:
enabled: true
level: 4 # oxipng level 1-6, higher = smaller but slower (NOT "quality")
jpeg:
enabled: true
quality: 80 # 1-100
ignore: # merged with built-in defaults (.dart_tool, build, .git, *.9.png)
- '**/vendor/**'OptimizeCommand loads --config <path> if given, else asset_optimizer.yaml at the monorepo root, else falls back to all-defaults. AssetOptimizerConfig.fromYamlFile reads keys under a top-level asset_optimizer: map.
Wiring
hooks/post_gen.dart:
Registers
devtools/scripts/asset_optimizerinto the melos workspace.Adds a path dependency on
asset_optimizertodevtools/monorepo_toolkit/pubspec.yaml(inserted before theexecutables:key).Injects
import 'package:asset_optimizer/asset_optimizer.dart';andaddCommand(AssetsCommand());intomonorepo_toolkit'scommand_runner.dartat the// --- Pro Commands ---marker.Writes
asset_optimizer.yamlat the project root with a starter config, the fileassets optimizereads by default. The content is the same asdevtools/scripts/asset_optimizer/example/asset_optimizer.yaml. An existing file is not changed.Adds the
brand-assetsskill's row to theAGENTS.mdskill index (appending the index to an olderAGENTS.md), and.claude/skills/brand-assets/scripts/node_modules/and__pycache__/to.gitignore.
All of this is skipped when isForMonorepo is false.
Agent skill: brand-assets
The brick also writes the brand-assets agent skill to .claude/skills/brand-assets/ and adds its row to the skill index in AGENTS.md. An AI agent (Claude Code, or any agent that reads AGENTS.md) uses it to draw brand art as code and ship it:
- SVG icons and illustrations, and festive variants of the logo, app icon and splash, rendered to PNG previews it inspects before it reports.
- Lottie animations written with python-lottie (
scripts/lottie_kit.py, with a workedexamples/logo_reveal.py). Every color is a named slot fromdesign/brand/brand.json, so a dark twin is written by slot. - Lottie
.jsonto.lottie(dotLottie) and back withscripts/dotlottie.mjs, which uses LottieFiles'@dotlottie/dotlottie-jsand validates every file it writes. - Wiring: the asset package and
asset-gen generate,assets optimize,flutter_launcher_icons,flutter_native_splash, and a Widgetbook use case.
The skill needs Python 3 with lottie, rlottie-python, Pillow and numpy, Node.js, and rsvg-convert; SKILL.md has the one-time setup. .gitignore gets the scripts' node_modules/ and __pycache__/. Running the brick again rewrites the skill folder. The brand assets showcase shows its output.
Why it ships with this brick, and why Pro. A skill ships with the brick that owns the capability it uses. The skill ends every asset in the asset pipeline this brick completes (assets optimize), and a project without this brick has no use for half of the skill. asset_optimizer is Pro, so the skill is Pro: a Free project never receives the files. A Pro or Enterprise project gets it at creation, and an existing project gets it with archipelago generate asset_optimizer.
Dependencies
Requires monorepo_toolkit generated first (the brick patches its pubspec.yaml/command_runner.dart). Depends on args, path, yaml, and the workspace's shared_scripts package — no other Archipelago brick.
Upgrading from 1.0.3 or earlier
Before 1.0.4, the brick wrote its starter config to example/asset_optimizer.yaml with a schema that assets optimize does not read. If your project has that file, delete it. Copy devtools/scripts/asset_optimizer/example/asset_optimizer.yaml to the project root as asset_optimizer.yaml, or run the brick again.
Changelog
Run archipelago brick info asset_optimizer to see the latest published version. Enterprise customers can read the full CHANGELOG.md in the brick source repository.