Manage icons in Android now that Material Icons is deprecated

a month ago

Your icons did not randomly break. Google deprecated the androidx.compose.material.icons libraries, which quietly ended the era of “magic” bundled icons. Now, icons must be managed like any other versioned asset.

Without a plan, you get red symbols after updates, one-off SVGs bloating the repo, and flaky CI. This guide shows how to replace the deprecated Material Icons pipeline with a reproducible, CI‑friendly icon system for both Compose and XML—from quick patches to full automation, formats, performance, and APK size.

What exactly was deprecated in Compose Material Icons (and why)?

Direct answer: Your Material Icons stopped working because the old androidx.compose.material:material-icons-* libraries are deprecated and no longer recommended or surfaced by tooling. Fix it by replacing them with your own icon assets (Material Symbols or custom vectors) and updating imports to use your managed icons instead of the old Icons.* enums.

The deprecated pieces are the pre-generated icon sets in:

  • androidx.compose.material:material-icons-core
  • androidx.compose.material:material-icons-extended

According to the Compose Material release notes, icons in these libraries were deprecated because they no longer have any positive performance impact or value (I0484d). Shipping giant pre-bundled icon enums now conflicts with the modern goal of trimming unused resources and keeping apps lean.

At the same time, Google’s design focus moved to Material Design 3 and the Compose Material 3 library. These newer components and themes are icon-agnostic: you bring your own ImageVector or painter instead of relying on baked-in icon sets.

Deprecation doesn’t instantly delete icons, but it breaks expectations. New templates and samples stop using the old APIs, IDE auto-complete stops highlighting them, and future major versions can remove them entirely. Google’s general deprecation guidance in places like AdMob’s lifecycle docs suggests a timeline where an API is supported, then deprecated, then sunset within a few years.

The conclusion: you now own your icon pipeline. No more magic libraries; you decide which icons to ship, how to generate them, and how to keep them reproducible in CI.

Direct fix: why your Material Icons stopped working and the 5‑minute patch

Direct answer: Your icons broke because you updated Compose or templates and are still depending on deprecated androidx.compose.material:material-icons-* libraries. To patch it, re-add or update those dependencies, provide explicit Material Symbols or custom vector assets, update imports, then clean and rebuild. This restores icons while you plan a proper migration.

5‑minute checklist

  • Check dependencies: In build.gradle, verify whether you still have:
    • implementation("androidx.compose.material:material-icons-core:…")
    • implementation("androidx.compose.material:material-icons-extended:…")
    If they disappeared during an upgrade, icons will go red.
  • Add explicit assets or new deps:
    • Quick patch: temporarily keep those dependencies (while they are still available).
    • Better: start importing Material Symbols or your own SVG-based assets and expose them as ImageVectors or drawable painters.
  • Re-import icons: After adding dependencies or new assets, update your imports so they resolve correctly.
  • Clean & rebuild: Run Build → Clean Project and then rebuild to clear stale references and previews.

Common failure modes after deprecation

  • Missing imports: Icons.Default.Add is red because androidx.compose.material.icons.Icons is no longer imported.
  • Red references after Compose update: Updating to newer Compose BOMs but removing icon dependencies causes unresolved symbols.
  • No IDE auto-suggest: Start typing Icons. and nothing useful appears because the underlying library is gone.
  • Preview errors: Compose previews fail to render when icon references throw at build time.

Minimal code update example

Legacy usage (deprecated icon pipeline):

import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add

Icon(
  imageVector = Icons.Filled.Add,
  contentDescription = "Add"
)

New usage (your managed icon):

import androidx.compose.runtime.Composable
import androidx.compose.ui.res.painterResource
// or import your generated ImageVector, e.g. AppIcons.Add

Icon(
  painter = painterResource(R.drawable.ic_add),
  contentDescription = "Add"
)

Or, if you generate an ImageVector in Kotlin:

object AppIcons {
  val Add: ImageVector = /* generated from SVG */
}

Icon(
  imageVector = AppIcons.Add,
  contentDescription = "Add"
)

This 5‑minute fix gets your UI compiling again. The rest of the article focuses on the long‑term solution: a proper, automated icon pipeline.

Understanding Material Icons vs Material Symbols in modern Android

From Material Icons to Material Symbols

The original Material Icons set introduced simple, mostly single-weight glyphs like home, search, and add. Material Symbols is the evolution: a richer collection with multiple stylistic axes—weight, grade, optical size, and fill—providing much finer control.

Google’s modern guidance is centered on Material 3, with Compose Material 3 as the reference implementation. Icons are expected to align with these updated shapes and curves.

What changed for Android developers

  • Naming: Material Symbols reuse familiar names (e.g., home) but combine with style axes (filled, outlined, rounded, sharp, etc.).
  • Sets: Instead of one big set, you now consciously pick from families like Outlined, Rounded, or Sharp as a design decision.
  • No built-in enums: Compose no longer encourages auto-generated enums like Icons.Filled.Home. You’re expected to manage your own vectors (via resources or code generation).

Size, variety, and design implications

Material Symbols offer many more glyphs and stylistic permutations than the older Material Icons sets. Qualitatively, that means you can match icon weight and fill to typography and component density more precisely, instead of one-size-fits-all glyphs.

These icons also reflect broader UX trends: smoother curves, more consistent corner radii, and shapes tuned for legibility. Similar shifts are visible across Google surfaces—for example, Google Play’s app icon changes highlighted in various design discussions and posts referencing around a 30% curve adjustment on store icons—indicating a general move toward softer, friendlier visuals.

For Android devs, the takeaway is clear: Material Symbols are the long-term default. Your icon tooling should be optimized for them but flexible enough to accommodate brand sets and third-party packs.

How to import Material Symbols manually into a Compose project

Direct answer: Download the SVG from the Material Symbols/Google Fonts site, convert it to a VectorDrawable via Android Studio’s Vector Asset tool or to an ImageVector via code generation, save it under res/drawable, then use painterResource() or an ImageVector field in your Compose code.

Step‑by‑step workflow

  • Download SVGs:
    • Go to the Material Symbols collection on Google Fonts or the Material Symbols website.
    • Pick the style (filled/outlined/rounded/sharp) and download the SVG.
  • Convert SVG → VectorDrawable or ImageVector:
    • Using Android Studio Vector Asset:
      • Right-click your module → New → Vector Asset.
      • Choose Local file (SVG) and select the downloaded icon.
      • Set a name like ic_nav_home and finish. This creates a VectorDrawable XML file.
    • Using Kotlin ImageVector.Builder (generated):
      • Use a tool or script that parses the SVG and writes a Kotlin file with ImageVector.Builder path data.
      • Place it in a icons or ui package and expose it via object AppIcons.
  • Store icons:
    • Compose & XML shared: Put the generated VectorDrawable XML in res/drawable or res/drawable-anydpi so both views and Compose can use it.
    • Compose-only: You can rely on generated ImageVector code if you don’t need XML support, but sharing drawables keeps things simpler.

Minimal Compose usage example (VectorDrawable)

@Composable
fun HomeIcon(contentDescription: String? = null) {
  Icon(
    painter = painterResource(R.drawable.ic_nav_home),
    contentDescription = contentDescription
  )
}

Material 3 Compose components (see compose-material3) are icon-agnostic. For example, NavigationBarItem or IconButton simply accept a Composable for the icon; whether that icon comes from a VectorDrawable or an ImageVector is up to you.

Manual import for XML/View apps: from SVG to VectorDrawable

Traditional non‑Compose pipeline

  • Download SVG: Get the icon SVG from Material Symbols or another provider.
  • Convert with Vector Asset wizard:
    • Right-click your module → New → Vector Asset.
    • Choose the SVG file and configure its name (e.g., ic_action_share).
    • Finish to generate the .xml VectorDrawable under res/drawable or res/drawable-anydpi.
  • Reference in layouts:
    • <ImageView
        android:layout_width="24dp"
        android:layout_height="24dp"
        android:src="@drawable/ic_action_share" />
    • Or with AppCompat for better back-compat:
      <androidx.appcompat.widget.AppCompatImageView
        android:layout_width="24dp"
        android:layout_height="24dp"
        app:srcCompat="@drawable/ic_action_share" />

API level considerations

VectorDrawable is fully supported on modern Android, and AndroidX AppCompat backports make it usable even on older API levels when you use app:srcCompat and the corresponding support libraries. You don’t need multiple bitmap densities for simple icons, which keeps APKs smaller and maintenance simpler.

This manual “download SVG → convert → commit VectorDrawable” process is exactly what you’ll later automate with scripts or Gradle tasks, eliminating the need to manually run the IDE wizard for every icon.

Batch‑download and auto‑import: building an icon pipeline instead of dragging files

Direct answer: Yes. You can define a declarative icon list, then use a Gradle task or external script to batch-download SVGs from Material Symbols (or other sources), convert them to VectorDrawables or ImageVector code, and place them into predictable folders. Run this step locally and in CI for reproducible icons.

Principles of an automated icon pipeline

  • Declarative icon spec:
    • A JSON, YAML, or Kotlin object listing icons, e.g.: name, source URL, style (filled/outlined), and target filename.
    • This file becomes the single source of truth for which icons your app ships.
  • Automation script:
    • Implemented as a Gradle task, Kotlin CLI, Python script, or Node tool.
    • Reads the spec and fetches SVGs from Material Symbols / Google Fonts or other APIs.
  • Conversion step:
    • For XML/View: convert SVGs into VectorDrawable XML.
    • For Compose-only options: generate Kotlin code with ImageVector.Builder paths.
  • Deterministic file placement:
    • Write generated XML to src/main/res/drawable-anydpi/ or res/drawable/.
    • Write generated Kotlin sources to build/generated/source/icons/ or a similar directory included in your source sets.

This mirrors Android’s broader deprecation lifecycle (support → deprecate → sunset, as described in resources like AdMob’s deprecation docs): when Google deprecates a library or changes formats, you just update your pipeline and regenerate, instead of hunting down icons by hand.

Example pseudo‑workflow

  • Gradle task: ./gradlew generateIcons
  • Icons spec → script: Task reads icons.json and invokes a CLI tool.
  • CLI tool:
    • Downloads or updates SVGs in /icons/src.
    • Converts them to VectorDrawable XML in app/src/main/res/drawable-anydpi.
    • Optionally generates AppIcons.kt with ImageVector mappings.
  • CI integration:
    • CI runs generateIcons before assemble.
    • Build fails if generated files are outdated compared to the spec.

The rest of this article will refine which formats to use, where to place files, and how to name and version icons so they fit cleanly into such a pipeline.

Best icon file formats for Android: SVG, VectorDrawable, ImageVector, PNG

Direct answer: Use SVG as your source-of-truth format, VectorDrawable XML for runtime in XML/views, and ImageVector (or painterResource from @drawable) for Compose. Keep PNGs only for complex multi-color art or legacy needs. Store vectors in res/drawable(-anydpi) and manage tint via themes, not hardcoded colors.

Format strengths and weaknesses

  • SVG (source format):
    • Great for designers and version control.
    • Not used directly at runtime in Android.
    • Ideal as the canonical source in a /icons directory that scripts read from.
  • VectorDrawable XML (runtime vector for views):
    • Compact, scalable, and natively supported by Android.
    • Single file scales across densities, unlike multiple PNGs.
    • Primary runtime format for XML/View UIs.
  • ImageVector (Compose vector):
    • Kotlin representation of vector paths.
    • Works seamlessly with Compose’s Icon() andImage() APIs.
    • Can either be generated directly from SVG or loaded from VectorDrawables via painterResource().
  • PNG (bitmap):
    • Useful for complex, multi-color illustrations, photos, or branding that doesn’t translate cleanly to vectors.
    • Heavier: you often need multiple density variants.
    • Scaling can introduce blurriness if not sized properly.

In general, SVG and VectorDrawable assets are smaller than maintaining multi-density PNG bundles, but real file sizes depend heavily on path complexity and icon detail.

Vectors also help control APK size by eliminating per-density assets and allowing the same drawable to be tinted and reused across light/dark themes. Compose Material 3 is designed around vector-based assets and dynamic theming, which makes vector icons the natural fit.

Where each file should live

  • SVG sources: /icons/src/*.svg (not shipped in APK).
  • VectorDrawable XML: app/src/main/res/drawable-anydpi/ or drawable/.
  • Generated ImageVector code (optional): app/build/generated/source/icons/ (or a dedicated :icons module).
  • PNGs (fallbacks/complex art): res/drawable-xxxhdpi/ and other density buckets only when vectors cannot be used.

Where to store icons: resource folders, modules, and naming conventions

  • VectorDrawable XML icons:
    • app/src/main/res/drawable-anydpi/ (preferred) or res/drawable/.
  • Night/density-specific assets:
    • Use res/drawable-night or density folders (drawable-xxhdpi, etc.) only when necessary, typically for PNG fallbacks or heavily branded graphics.
  • Shared icon modules:
    • In larger apps, create a :design:icons or :core:ui module.
    • Place shared VectorDrawables and generated AppIcons.kt there.
    • Consumer modules depend on this module for consistent icon usage.

Naming conventions

  • Prefix by domain:
    • ic_nav_home for navigation icons.
    • ic_action_share for toolbar actions.
    • ic_logo_brand for brand-specific glyphs.
  • Avoid style tokens unless needed:
    • Prefer ic_nav_home instead of ic_nav_home_filled, unless you intentionally ship multiple variants.
    • If multiple styles exist, use suffixes: ic_nav_home_outlined, ic_nav_home_filled.

Central Kotlin access for Compose

Expose your icons via a single Kotlin object so usage across the app is consistent.

object AppIcons {
  val Home = painterResource(R.drawable.ic_nav_home)
  val Share = painterResource(R.drawable.ic_action_share)
}

@Composable
fun NavHomeIcon(contentDescription: String?) {
  Icon(
    painter = AppIcons.Home,
    contentDescription = contentDescription
  )
}

With consistent naming and a central access layer, you can easily search for icon usage, refactor names, or let scripts map spec entries to filenames. This also makes it straightforward to swap icon sets (e.g., from Material Symbols to a brand pack) by updating AppIcons instead of chasing hundreds of call sites.

Tinting and theming icons in Compose vs XML

Direct answer: In Compose, tint icons with MaterialTheme.colorScheme values (e.g., onSurface) using Icon(). In XML, use android:tint or app:tint with theme attributes like ?attr/colorOnSurface. Avoid hardcoded colors, and keep multi-color icons mostly untinted.

Tinting in Compose

  • Use Icon() with theme-driven tinting:
    @Composable
    fun ThemedIcon(painter: Painter, contentDescription: String?) {
      Icon(
        painter = painter,
        contentDescription = contentDescription,
        tint = MaterialTheme.colorScheme.onSurface
      )
    }
  • For monochrome icons, tint is ideal for adapting to dark/light themes.
  • For multi-color icons (e.g., flags, logos), avoid tint; encode colors in the vector paths sparingly and only where necessary.

Compose Material 3 is fully colorScheme-driven, so aligning icon tints with colorScheme values ensures your icons adapt seamlessly to dynamic theming.

Tinting in XML/View

  • Use android:tint or, with AppCompat, app:tint:
    <androidx.appcompat.widget.AppCompatImageView
      android:layout_width="24dp"
      android:layout_height="24dp"
      app:srcCompat="@drawable/ic_nav_home"
      app:tint="?attr/colorOnSurface" />
  • Prefer theme attributes (?attr/colorOnSurface, ?attr/colorPrimary) over hardcoded hex values.
  • Keep multi-color drawables untinted unless you have a specific effect in mind.

Consistent tinting supports a coherent, high-quality visual identity. External UX research, such as work summarized by PocketGamer indicating that optimized app store icons can attract up to 25% more users, underscores how crucial icon treatment is for perceived quality—even though that particular stat focuses on store icons, the same principle extends to in-app iconography.

APK size and performance: how many icons is too many?

Direct answer: Keep icons as vectors (VectorDrawable/ImageVector), ship only the icons you actually use, and avoid redundant style variants. Centralize your icon spec, let resource shrinking remove unused assets, and integrate icon checks into CI to keep APK size lean and performance acceptable.

APK size considerations

  • Vector drawables:
    • Generally small, especially for simple icons.
    • Adding dozens or even a hundred simple icons often adds only a modest increase in size compared to multiple-density PNGs.
  • PNGs:
    • Each icon may require several density variants.
    • Can add up to megabytes of extra weight depending on resolution and number of icons.
  • Style variants:
    • The biggest waste comes from shipping filled + outlined + rounded + sharp variants when your design uses only one or two.
    • Choose one primary family (e.g., Filled or Outlined) and stick to it.

Runtime performance tradeoffs

  • Vectors (ImageVector/VectorDrawable):
    • Require the GPU/CPU to rasterize paths at runtime.
    • For typical UI icons, overhead is minimal on modern devices.
    • Scaling and tinting are “free” from a design perspective—no extra assets.
  • PNGs:
    • Fast to draw because they’re pre-rasterized.
    • Better for extremely complex illustrations or heavy animations.
    • Costly in storage and network bandwidth.

Google deprecated the pre-generated Material icon libraries because their size no longer delivered performance benefits (see the Compose Material notes at compose-material). That supports the model of shipping only what you use, not entire icon catalogs.

Practical optimization strategies

  • Central icon spec: Define the exact set of icons you ship in one file (JSON/Kotlin). No spec entry → no icon.
  • Unused icon detection: Add build-time lint checks or scripts that compare the spec, resources, and usage to flag dead icons.
  • Resource shrinking: Enable R8/ProGuard and resource shrinking; unused vector resources can be removed as well.
  • Profile only if needed: For most products, icons are not the primary performance bottleneck; profile only if you render extremely complex vectors at large sizes.

Exact benchmarks for ImageVector vs PNG vary by device, icon complexity, and usage patterns. Instead of chasing a universal number, focus on good defaults: vectors for icons, PNG for special cases, and strict control over which icons ship.

Versioning, back‑compat, and rollback strategies for icons

Icons are no longer anonymous binaries hidden in a library. They’re part of your design system, evolving alongside Material 3 updates and ecosystem shifts like Google Play’s app icon curvature changes discussed in various design posts. You need controlled, reversible icon updates.

Versioning strategies

  • Source directory for SVGs:
    • Maintain an /icons directory at the root of your repo.
    • Store raw SVGs there; automation reads these and generates runtime assets.
  • Visual CHANGELOG:
    • Create /icons/CHANGELOG.md to document icon additions, removals, and major style changes.
    • Link changes to product features or releases.
  • Semantic icon versions:
    • In your icon spec, introduce a high-level version tag, e.g., "version": "2.0" when you switch from legacy Material Icons style to Material Symbols/Material 3 style.
    • Use tags in Git (e.g., icons-v1, icons-v2) to anchor big redesigns.

Back‑compat and rollback

  • Legacy folder:
    • Move old icons to /icons/legacy when you replace them.
    • Maintain a mapping (old → new) in your spec or documentation.
  • Declarative rollbacks:
    • A rollback should mean: revert the spec to a previous version in Git, then rerun the icon generation script.
    • Avoid manual deletion of drawable/XML files; generated assets should always match whatever the spec says.
  • Align with Android’s lifecycle:
    • Just as Android frameworks move from supported → deprecated → sunset (as described, for example, in AdMob deprecation docs), treat icon sets the same way.
    • Announce deprecations internally (e.g., “icons-v1 is deprecated; v2 is current”) and set a removal window.

CI/CD integration: making icons reproducible and reviewable

CI‑friendly icon workflow

  • Commit the spec:
    • Keep icons.json (or a Kotlin/JSON config) under version control.
    • Every icon change starts by editing this spec.
  • Generation step:
    • Add a Gradle or CLI task (e.g., generateIcons) that reads the spec and generates all runtime artifacts: VectorDrawable XML and optionally AppIcons.kt with ImageVector references.
    • Make this task deterministic; given the same spec and SVG sources, output is identical.
  • CI integration:
    • On CI, run generateIcons before assemble.
    • Fail the build if the working tree is dirty afterward (ensures spec and generated files are in sync).

Commit vs generate-only on CI

  • Commit generated assets:
    • Pros: Easier code review (diffs in vector XML/Kotlin); builds remain deterministic even if upstream icon sources change or go offline.
    • Cons: More files in the repo; requires discipline to keep generated files updated.
  • Generate on CI only:
    • Pros: Cleaner repo; only source SVGs and spec live in Git.
    • Cons: You depend on external icon APIs being stable and reachable; code review for visual changes is harder unless you add screenshots.

Suggested CI steps

  • Run ./gradlew generateIcons early in the pipeline.
  • Check for changes (e.g., git diff --exit-code) to ensure developers committed generated assets when required.
  • Optionally, run screenshot tests for critical screens involving key icons and compare against baselines.

Just as research reported by PocketGamer shows that well-optimized store icons can significantly boost user acquisition, keeping in-app icons consistent across deployments via CI supports a polished, trustworthy brand experience for returning users.

Answering common migration questions (PAA corner)

Why did my Material Icons stop working in Android Studio and how do I fix it?

Your icons rely on deprecated androidx.compose.material:material-icons-* libraries. After updating Compose or templates, those dependencies may be missing or discouraged, so Icons.Filled.* references fail. Re-add the dependencies temporarily, or better, import Material Symbols as VectorDrawables/ImageVectors and update your code to use your own AppIcons instead.

How do I import Material Symbols or material icons manually into a Compose project?

Download the SVG from Material Symbols/Google Fonts, run Android Studio’s Vector Asset wizard to generate a VectorDrawable or use a generator to create an ImageVector in Kotlin, save it under res/drawable or a generated source directory, then reference it via painterResource() or an AppIcons object in your Compose code.

Is there a way to batch-download and auto-import Material icons into my Android project (VectorDrawable / ImageVector)?

Yes. Define a JSON/Kotlin spec listing icon names and sources, write a Gradle/CLI script that downloads SVGs from Material Symbols or other providers, converts them to VectorDrawable XML or ImageVector code, writes them into res/drawable and generated source folders, and run this task locally and in CI for reproducible icon sets.

What are the best file formats, resource locations, and tinting practices for icons in Android (Compose vs XML)?

Use SVG as the design/source format; VectorDrawable XML in res/drawable(-anydpi) for runtime; ImageVector or painterResource(@drawable) for Compose; and PNG only for complex artwork. Tint icons via Material 3 theme colors (colorScheme in Compose, theme attributes in XML) rather than hardcoded colors for consistent dark/light theming.

How should I organize, version, and optimize icon assets to minimize APK size and make CI/CD friendly?

Keep SVGs under an /icons directory, define a single icon spec file, and generate vectors programmatically. Ship only used icons, rely on resource shrinking, and centralize naming (e.g., ic_nav_*, ic_action_*). Integrate icon generation into CI, fail builds on mismatches between spec and assets, and tag major icon revisions for easy rollback.

Remember that Compose Material icon libraries are deprecated because they no longer offer performance benefits (compose-material), and Material 3 is now the canonical design target (compose-material3).

End‑to‑end migration checklist: from deprecated Material Icons to a modern icon system

  • Audit current icons: Use IDE search and Gradle dependency reports to list all icon usages (Compose Icons.* and XML @drawable).
  • Remove deprecated dependencies: Phase out androidx.compose.material:material-icons-core and material-icons-extended, replacing them with your own assets over time.
  • Choose your primary icon set: Decide on Material Symbols, custom brand icons, or a hybrid, and document the chosen style family (e.g., Filled).
  • Define an icon spec: Create a JSON/Kotlin spec listing each icon: name, style, and source path/URL.
  • Decide on formats: Use SVG as the source of truth; VectorDrawable XML and ImageVector/painterResource for runtime; PNG only where vectors are insufficient.
  • Set locations and naming: Store VectorDrawables in res/drawable-anydpi, group them in a shared :design:icons module if modularized, and enforce consistent names like ic_nav_home.
  • Implement automation: Write a script or Gradle task to fetch SVGs, convert to VectorDrawable/ImageVector, and place them in the correct folders based on the spec.
  • Integrate into CI: Run the icon generation task before builds, fail on mismatched or uncommitted generated assets, and optionally add visual regression checks.
  • Document theming rules: Specify which theme colors to use for tints in Compose and XML, aligned with your Material 3 theme (light, dark, dynamic colors).
  • Plan versioning & rollback: Tag icon releases (e.g., icons-v1, icons-v2), keep legacy icons in a separate folder, and always roll back by reverting the spec and regenerating.

This checklist is your path from “my icons suddenly broke” to a disciplined, future-proof icon system.

Future‑proofing: preparing for the next icon or UI deprecation

Key lessons from the Material Icons deprecation

  • Avoid implicit giant libraries: The deprecation of Compose Material icon libraries (compose-material) shows that depending on monolithic, pre-bundled icons can backfire when maintainers trim them for performance or size reasons.
  • Treat icons like code: They should be versioned, reviewed, and generated deterministically from a spec and sources, just like API clients or generated models.
  • Anchor in current guidelines, but keep flexibility: Use Material 3 as your baseline (compose-material3), but keep your pipeline flexible enough to plug in brand icon sets or new Google collections without rewriting everything.

Stay ahead of upcoming changes

  • Monitor Android Release Notes and “Now in Android” posts such as Now in Android for early warnings about drawable, theming, or UI changes.
  • Schedule periodic design reviews (e.g., yearly) to evaluate if icons still match current guidelines and brand direction.

Connect to broader icon optimization thinking

Industry resources like ASOMobile’s app icon trends and best practices and PocketGamer’s research on app icon optimization emphasize how crucial icons are for acquisition and perception. While these focus on store icons, the same principle applies in-app: consistent, high-quality icons make your product feel polished and coherent.

By moving off deprecated Material Icons and investing in a lean, automated icon architecture, you’re not just fixing today’s breakage—you’re building a system robust enough to survive the next wave of design, framework, or library changes with minimal friction.

The Blueprint Table

Use this 5‑day blueprint as a practical implementation plan (expressed as a linear list rather than a table to stay mobile‑friendly):

Day 1 – Audit and dependency cleanup

  • Scan the codebase for usages of Icons.* and Material Icons.
  • Run Gradle dependency reports to find androidx.compose.material:material-icons-*.
  • Document all current icon entry points (Compose and XML).

Day 2 – Define spec and formats

  • List the icons you actually need (by feature/screen).
  • Choose your primary icon family (Material Symbols vs brand/custom).
  • Define your icon spec file (name, style, source URL/path).
  • Confirm: SVG = source, VectorDrawable/ImageVector = runtime.

Day 3 – Implement automation

  • Create a simple script or Gradle task that reads the icon spec.
  • Implement “download SVG → convert to VectorDrawable/XML or ImageVector → write to res/drawable/generated sources.”
  • Test regeneration locally and ensure idempotent output.

Day 4 – Wire into CI and theming

  • Integrate the icon generation task into your CI pipeline before builds.
  • Add a check to fail builds if spec and generated assets diverge.
  • Document and enforce tinting/theming rules in Compose and XML.

Day 5 – Naming, modularization, and full migration

  • Refine naming conventions (ic_nav_*, ic_action_*, ic_logo_*).
  • Group icons into shared modules (e.g., :design:icons).
  • Run a full migration pass, replacing deprecated Material Icon references with your new AppIcons.
  • Tag the release (e.g., icons-v1) and document rollback strategy.
Manage icons in Android now that Material Icons is deprecated | AI Solopreneur