🎨 Assetify

Pub Package License: MIT Flutter

Type-safe, auto-generated asset constants for Flutter projects 🚀

Assetify eliminates the pain of managing asset paths in Flutter by generating type-safe Dart constants from your pubspec.yaml configuration. Say goodbye to typos and hello to IDE autocomplete!

✨ Features

  • 🛡️ Type Safety: Catch asset path errors at compile time
  • 🔍 IDE Autocomplete: Discover assets easily with IntelliSense
  • 🎯 Smart Grouping: Automatically organizes assets by type (images, fonts, SVGs, etc.)
  • 🔄 Watch Mode: Real-time regeneration during development
  • 🎛️ Flutter Helpers: Optional widget extensions for quick Image/SVG/Lottie creation
  • CLI-First: Simple commands with sensible defaults
  • 📦 Lightweight: Focused solely on asset management

🚀 Quick Start

1. Installation

Add assetify to your Flutter project:

dev_dependencies:
  assetify: ^1.0.0

Run:

flutter pub get

2. Configure Assets

Ensure your pubspec.yaml has assets configured:

flutter:
  assets:
    - assets/images/
    - assets/icons/
    - assets/lottie/
  fonts:
    - family: Roboto
      fonts:
        - asset: assets/fonts/Roboto-Regular.ttf

3. Generate Constants

# Generate once
dart run assetify:generate

# Watch for changes during development
dart run assetify:watch

4. Use in Your Code

import 'assetify.g.dart';

// Before: Error-prone string literals
Image.asset('assets/images/cat.png')  // ❌ Typo risk

// After: Type-safe constants
Image.asset(Assets.images.cat)  // ✅ Type-safe + autocomplete
Assets.images.cat.asImage()     // ✅ Convenient helper

📖 Usage Guide

CLI Commands

Command Description Example
generate Generate asset constants once dart run assetify:generate
watch Watch and regenerate on changes dart run assetify:watch

CLI Options

Option Short Description Default
--output -o Output file path lib/assetify.g.dart
--class-name -c Root class name Assets
--widgets Enable Flutter helpers true
--assets Extra asset paths (comma-separated)
--verbose -v Enable verbose logging false

Examples

# Custom output location
dart run assetify:generate -o lib/generated/assets.dart

# Custom class name
dart run assetify:generate -c MyAssets

# Include additional assets
dart run assetify:generate --assets "docs/images,extra/files"

# Verbose output
dart run assetify:generate --verbose

🎯 Generated Output

Example Generated File

// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: constant_identifier_names

import 'package:flutter/widgets.dart';

/// Asset references for this project.
/// Generated by Assetify: https://pub.dev/packages/assetify
class Assets {
  const Assets._();

  // Flat constants for all assets
  static const String imagesCatPng = 'assets/images/cat.png';
  static const String iconsHomePng = 'assets/icons/home.png';
  static const String lottieLikeAnimationJson = 'assets/lottie/like_animation.json';
  static const String svgLogoSvg = 'assets/svg/logo.svg';

  // Grouped access
  static const Images images = Images._();
  static const Icons icons = Icons._();
  static const Lotties lotties = Lotties._();
  static const Svgs svgs = Svgs._();
  static const Fonts fonts = Fonts._();
}

class Images {
  const Images._();
  final String catPng = 'assets/images/cat.png';
}

class Icons {
  const Icons._();
  final String homePng = 'assets/icons/home.png';
}

// Flutter helper extensions (when enabled)
extension AssetImageX on String {
  /// Creates an Image widget for raster images
  Image asImage({Key? key, BoxFit? fit}) => Image.asset(this, key: key, fit: fit);
  
  /// Creates an AssetImage provider
  AssetImage asImageProvider() => AssetImage(this);
}

extension SvgAssetX on String {
  /// Creates an SVG widget (requires flutter_svg)
  SvgPicture asSvg({Key? key, BoxFit? fit}) => SvgPicture.asset(this, key: key, fit: fit);
}

extension LottieAssetX on String {
  /// Creates a Lottie animation (requires lottie package)
  LottieBuilder asLottie({Key? key, bool repeat = true}) => 
    Lottie.asset(this, key: key, repeat: repeat);
}

Usage Examples

// Multiple ways to access the same asset
Assets.imagesCatPng              // Flat access
Assets.images.catPng             // Grouped access

// Widget helpers (when Flutter deps detected)
Assets.images.cat.asImage()   // Quick Image widget
Assets.svgs.logo.asSvg()      // SVG widget
Assets.lotties.likeAnimationJson.asLottie()  // Lottie animation

// Traditional usage still works
Image.asset(Assets.images.catPng)
SvgPicture.asset(Assets.svgs.logo)

🔧 Programmatic API

For advanced use cases, you can use Assetify programmatically:

import 'dart:io';
import 'package:assetify/assetify.dart';
import 'package:mason_logger/mason_logger.dart';

void main() async {
  // Read project configuration
  final reader = PubspecReader(File('pubspec.yaml'));
  final project = await reader.read();
  
  // Generate assets
  final generator = AssetGenerator(
    project: project,
    outputFile: File('lib/assetify.g.dart'),
    className: 'Assets',
    generateWidgets: true,
    logger: Logger(),
  );
  
  await generator.generate();
}

📁 Project Structure

This package works with standard Flutter project layouts:

your_project/
├── pubspec.yaml
├── lib/
│   ├── main.dart
│   └── assetify.g.dart  # Generated file
└── assets/
    ├── images/
    │   ├── cat.png
    │   └── dog.jpg
    ├── icons/
    │   └── home.png
    ├── fonts/
    │   └── Roboto-Regular.ttf
    └── lottie/
        └── animation.json

🎨 Example Project

Check out the included example:

cd example
flutter pub get
dart run ../bin/assetify.dart generate
flutter run

The example demonstrates:

  • ✅ Image assets with helper methods
  • ✅ SVG assets (with flutter_svg)
  • ✅ Lottie animations
  • ✅ Custom fonts
  • ✅ Generated constants usage

💡 Tips & Best Practices

Asset Organization

flutter:
  assets:
    - assets/images/          # Images auto-grouped
    - assets/icons/           # Icons auto-grouped
    - assets/lottie/          # Lottie files auto-detected

Naming Conventions

  • File extensions are automatically removed: cat_image.pngcatImage
  • Assets are converted to camelCase: home-icon.svghomeIcon
  • Folders become nested classes: images/cat.pngAssets.images.cat
  • Invalid identifiers are sanitized: 2D-logo.svgd2Logo

Development Workflow

  1. Use dart run assetify:watch during development
  2. Assets update automatically when files change
  3. IDE autocomplete guides you to available assets

🔧 Configuration

Interactive Setup

If no assets are configured in pubspec.yaml, Assetify will prompt you:

🔍 No assets configured under flutter: assets: in pubspec.yaml
Enter an assets path to include (or press Enter to skip): assets/
➕ Including: assets/

Conditional Helpers

Widget helpers are automatically included based on your dependencies:

  • Flutter: Basic asImage() helper always available
  • flutter_svg: asSvg() helper added when package detected
  • lottie: asLottie() helper added when package detected

🐛 Troubleshooting

Common Issues

Q: "No assets found"

# Check your pubspec.yaml has assets listed
flutter:
  assets:
    - assets/images/

Q: "Generated file not updating"

# Clear and regenerate
rm lib/assetify.g.dart
dart run assetify:generate

Q: "Import errors in generated file"

# Check your dependencies
flutter pub deps

Asset Detection

  • Images: .png, .jpg, .jpeg, .gif, .webp, .bmp, etc.
  • SVGs: .svg files
  • Lottie: .json files in folders containing "lottie" or "animation"
  • Fonts: Files declared in pubspec.yaml fonts section
  • Hidden files (.DS_Store, Thumbs.db) are automatically ignored

🤝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

Development Setup

  1. Clone the repository
  2. Run flutter pub get
  3. Make your changes
  4. Run tests: dart test
  5. Submit a pull request

📄 License

This project is licensed under the BSD 3-Clause License - see the LICENSE file for details.

🙏 Acknowledgments

  • Built with ❤️ for the Flutter community
  • Inspired by similar tools in other ecosystems
  • Thanks to all contributors and users!

Made with ❤️ by the Ionic Errrrs Code Team

Libraries

assetify
Assetify - Type-safe asset constants generator for Flutter projects.