json_annotation_tools 0.1.7 copy "json_annotation_tools: ^0.1.7" to clipboard
json_annotation_tools: ^0.1.7 copied to clipboard

Transform cryptic JSON parsing errors into crystal-clear, actionable error messages. Perfect companion to json_annotation.

JSON Annotation Tools ๐Ÿ› ๏ธ #

pub package License: MIT

Stop wrestling with cryptic JSON parsing errors! This package provides powerful debugging tools and safe parsing utilities that make JSON deserialization errors crystal clear and easy to fix.

[Error Comparison Demo] Before vs After: See how error messages transform from cryptic to crystal clear

๐ŸŽฏ Why You Need This #

Ever seen this frustrating error?

type 'String' is not a subtype of type 'int'

And spent hours figuring out which field in your JSON caused it? Those days are over.

Before vs After #

โŒ Before (Standard JSON parsing):

// Unclear error: "type 'String' is not a subtype of type 'int'"
// Which field? What value? Who knows! ๐Ÿคทโ€โ™‚๏ธ
User.fromJson(json);

โœ… After (With JSON Annotation Tools):

// Crystal clear error message:
// "โŒ Error parsing key 'age': expected int, but got String. Value: "25""
User.fromJsonSafe(json);

[Complete Demo Flow] ๐ŸŽฌ See the complete debugging experience in action

๐Ÿš€ Features #

๐ŸŽฏ Revolutionary Code Generation #

  • ๐Ÿช„ Zero-Hassle Setup: Just add @SafeJsonParsing() annotation - that's it!
  • ๐Ÿš€ Automatic Generation: Build runner creates optimized safe parsing methods
  • โšก Best Performance: Generated code is as fast as hand-written safe parsing
  • ๐Ÿ”ง Highly Customizable: Field-level annotations for enhanced error context

โšก Manual Convenience Methods #

  • ๐ŸŽฏ Clean Convenience Methods: json.getSafeInt(), getSafeString(), getSafeBool() and more!
  • ๐Ÿš€ No More Manual Parsers: Gone are the days of (v) => v as int everywhere
  • โšก Best Performance: Same speed as manual parsing, but way cleaner code
  • ๐Ÿ”ง Comprehensive Coverage: 12+ convenience methods for all common types

๐Ÿ“Š Crystal-Clear Error Messages #

  • ๐Ÿ” Pinpoint Error Location: Know exactly which JSON field caused the parsing error
  • ๐Ÿ“ Detailed Error Messages: See the expected type, actual type, and problematic value
  • ๐Ÿง  Smart Suggestions: AI-powered field name suggestions for typos and mismatches
  • ๐Ÿ“‹ Copy-Paste Solutions: Ready-to-use code fixes for every error scenario

๐Ÿ›ก๏ธ Bulletproof Parsing #

  • ๐Ÿ›ก๏ธ Type Safety: Catch type mismatches before they crash your app
  • ๐Ÿšซ Missing Field Detection: Clear warnings for missing required fields
  • ๐Ÿ”„ Seamless Integration: Works perfectly with json_annotation and json_serializable
  • โšก Zero Performance Impact: Only active during parsing errors
  • ๐ŸŒ Cross-Platform: Works on iOS, Android, Web, macOS, Windows, Linux

๐Ÿ“ฑ Interactive Demo App #

Experience the power of enhanced error messages with our interactive demo app:

[Demo App Home]

Try all features live on Android, iOS, or Web!

What You'll See: #

  • ๐Ÿšจ Real Error Comparisons: Before vs after side-by-side
  • ๐Ÿ”ง Copy-Paste Solutions: Ready-to-use code fixes
  • ๐ŸŽฏ Smart Suggestions: AI-powered field name matching
  • ๐Ÿ” Advanced Diagnostics: Property mapping analysis
  • โšก Live Testing: Try different JSON scenarios instantly

๐Ÿ“ฆ Installation #

Add to your pubspec.yaml:

dependencies:
  json_annotation_tools: ^0.1.7  # ๐Ÿš€ Latest version!
  json_annotation: ^4.9.0

dev_dependencies:
  build_runner: ^2.4.12  # For @SafeJsonParsing() code generation
  json_serializable: ^6.8.0

๐ŸŽฎ Quick Start #

Just add one annotation and get automatic safe parsing with enhanced error messages! โœจ

# Adds @SafeJsonParsing() and part 'model.safe_json_parsing.g.dart';
dart run json_annotation_tools init

# Preview without writing changes
dart run json_annotation_tools init --dry-run

This scans your lib/ folder for @JsonSerializable models, inserts the missing @SafeJsonParsing() annotation, and ensures the extra part directive is present so you can jump straight to code generation.

Step 1: Annotate Your Model

import 'package:json_annotation/json_annotation.dart';
import 'package:json_annotation_tools/json_annotation_tools.dart';

part 'user.g.dart';
part 'user.safe_json_parsing.g.dart';  // ๐Ÿ”ฅ This will be generated!

@JsonSerializable()
@SafeJsonParsing() // โ† Magic happens with just this line!
class User {
  final int id;
  final String name;
  final int age;
  final String? email; // Nullable fields handled automatically
  
  User({required this.id, required this.name, required this.age, this.email});
  
  // Standard json_serializable methods (unchanged)
  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
  Map<String, dynamic> toJson() => _$UserToJson(this);
  
  // ๐Ÿš€ AUTO-GENERATED: UserSafeJsonParsing.fromJsonSafe(json) method with enhanced errors!
}

Step 2: Create build.yaml (one-time setup)

# build.yaml (in your project root)
targets:
  $default:
    builders:
      json_annotation_tools|safe_json_parsing:
        enabled: true
      json_serializable|json_serializable:
        enabled: true

Step 3: Generate Code

# Generate the safe parsing methods
flutter packages pub run build_runner build
# or
dart run build_runner build

Step 4: Use Enhanced Parsing & See Error Messages

final problematicJson = {
  'id': 'not-a-number', // โŒ Should be int, got String
  'name': 'John Doe',
  'age': 25,
  'email': 'john@example.com',
};

try {
  // ๐Ÿš€ Use the auto-generated safe method
  final user = UserSafeJsonParsing.fromJsonSafe(problematicJson);
  print('Success: $user');
} catch (e) {
  // ๐Ÿ” Enhanced error message appears here!
  print('Enhanced Error: $e');
  
  /* Output:
  ๐Ÿšจ OOPS! There's a problem with your JSON data:
  
  ๐Ÿ” EXACT PROBLEM DIAGNOSIS:
     โŒ Field 'id' has the wrong data type
  
  ๐Ÿ“Š TYPE COMPARISON:
     Expected: int (whole number)
     Got: String (text)
     Value: "not-a-number"
  
  ๐Ÿ”ง How to fix this (3 easy options):
  1. Fix your API to return: {"id": 123}
  2. Update your model: final String id;
  3. Add conversion: int.tryParse(json['id'])
  */
}

Want zero call-site changes?

Create a single helper or service wrapper that always funnels through the generated safe method:

class UserParser {
  static User parse(Map<String, dynamic> json) =>
      UserSafeJsonParsing.fromJsonSafe(json);
}

// Use everywhere else
final user = UserParser.parse(apiResponse);

This keeps your UI/business layers unchanged while guaranteeing enhanced diagnostics.

๐ŸŽฏ Key Benefits:

  • ๐Ÿช„ Zero Manual Work: Just add @SafeJsonParsing() annotation
  • ๐Ÿš€ Auto-Generated: UserSafeJsonParsing.fromJsonSafe() method created automatically
  • โšก Best Performance: Generated code is as fast as hand-written safe parsing
  • ๐Ÿ” Enhanced Errors: Crystal-clear error messages built into generated method
  • ๐Ÿ”ง Production Ready: Perfect for error logging (Crashlytics/Sentry)

โšก Alternative: Manual Convenience Extensions #

Transform your JSON parsing from hassle to happiness with super clean convenience methods:

import 'package:json_annotation_tools/json_annotation_tools.dart';

@JsonSerializable()
class User {
  final int id;
  final String name;
  final int age;
  final String? email;
  
  User({required this.id, required this.name, required this.age, this.email});
  
  // Standard json_serializable methods (unchanged)
  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
  Map<String, dynamic> toJson() => _$UserToJson(this);
  
  // ๐Ÿš€ ENHANCED: Safe parsing with crystal-clear error messages
  factory User.fromJsonSafe(Map<String, dynamic> json) {
    return User(
      id: json.getSafeInt('id'),           // Clean convenience methods!
      name: json.getSafeString('name'),     // No more manual parsers!
      age: json.getSafeInt('age'),         // Automatic type conversion!
      email: json.getNullableSafeString('email'), // Nullable support!
    );
  }
}

Before vs After:

// ๐Ÿ˜ค OLD WAY (Manual hassle):
id: json.getSafe('id', (v) => v as int),
name: json.getSafe('name', (v) => v as String),

// ๐Ÿš€ NEW WAY (Clean convenience):
id: json.getSafeInt('id'),      // So much cleaner!
name: json.getSafeString('name'), // Zero hassle!

๐Ÿ”ง Alternative: Custom Parsers (For advanced control) #

If you need maximum control with custom parsing logic:

import 'package:json_annotation_tools/json_annotation_tools.dart';

@JsonSerializable()
class User {
  final int id;
  final String name;
  final int age;
  
  User({required this.id, required this.name, required this.age});
  
  // Standard method
  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
  
  // Manual safe method with extensions
  factory User.fromJsonSafe(Map<String, dynamic> json) {
    return User(
      id: json.getSafeInt('id'),     // Convenience methods
      name: json.getSafeString('name'),
      age: json.getSafeInt('age'),
    );
  }
}

3. Handle problematic JSON gracefully #

final problematicJson = {
  'id': 123,
  'name': 'John Doe',
  'age': '25', // Oops! String instead of int
};

try {
  final user = User.fromJsonSafe(problematicJson);
} catch (e) {
  print(e);
  // Output: โŒ Error parsing key 'age': expected int, but got String. Value: "25"
  // Now you know exactly what to fix!
}

๐Ÿงฐ Command-Line Setup Assistant #

Make onboarding effortless with the bundled CLI:

dart run json_annotation_tools init
  • Annotates automatically โ€“ adds @SafeJsonParsing() next to every @JsonSerializable model.
  • Fixes missing part files โ€“ ensures part 'model.safe_json_parsing.g.dart'; is present.
  • Dry-run friendly โ€“ append --dry-run to preview the diff.
  • Verbose mode โ€“ use --verbose to list already compliant files.

๐Ÿ’ก Tip: add this to a pre-commit hook or CI check so new models always ship with safe parsing baked in.

๐ŸŽฏ Real-World Examples #

๐Ÿ” How to See Enhanced Error Messages #

The most common question: "I added @SafeJsonParsing(), but how do I see the enhanced error messages?"

Answer: Use try-catch with the generated method!

// โŒ WRONG: Using standard method (cryptic errors)
final user = User.fromJson(problematicJson); // Type 'String' is not a subtype...

// โœ… CORRECT: Using generated safe method (enhanced errors)
try {
  final user = UserSafeJsonParsing.fromJsonSafe(problematicJson);
  print('Success: $user');
} catch (e) {
  print('๐Ÿ“‹ Full Enhanced Error:');
  print(e.toString()); // ๐Ÿ” See complete detailed diagnosis here!
  
  // ๐Ÿญ In production, log this to your error service:
  // crashlytics.recordError(e, null);
  // logger.error('JSON parsing failed: ${e.toString()}');
}

๐Ÿš€ Production API Service Pattern #

// Example API service using @SafeJsonParsing()
class UserService {
  Future<User> fetchUser(int id) async {
    try {
      final response = await dio.get('/api/users/$id');
      
      // ๐Ÿš€ Use auto-generated safe method with enhanced errors
      return UserSafeJsonParsing.fromJsonSafe(response.data);
      
    } catch (e) {
      // ๐Ÿ“ Enhanced error messages help debug API issues 10x faster
      logger.error('User parsing failed for ID $id: ${e.toString()}');
      
      // ๐ŸŽฏ Show user-friendly message
      throw UserFetchException('Unable to load user data');
    }
  }
}

๐Ÿ”ง Advanced Field-Level Configuration #

@JsonSerializable()
@SafeJsonParsing(
  validateRequiredKeys: true,  // Check all keys exist first
  methodName: 'parseProductSafe'  // Custom method name
)
class Product {
  final String id;
  
  @SafeJsonField(
    description: 'Product price in USD',
    expectedFormat: 'Positive number (e.g., 19.99)',
    commonValues: ['9.99', '19.99', '29.99'],
  )
  final double price;
  
  @JsonKey(name: 'is_available')
  @SafeJsonField(
    description: 'Product availability status',
    commonValues: ['true', 'false'],
  )
  final bool isAvailable;
  
  // ๐Ÿš€ AUTO-GENERATED: ProductSafeJsonParsing.parseProductSafe(json)
  // Enhanced errors include field descriptions and common values!
}

API Response Debugging #

// When your API suddenly returns unexpected data types
final apiResponse = {
  'user_id': '12345',    // Should be int, but API returned string
  'balance': 'null',     // Should be double, but got string "null"
  'premium': 1,          // Should be bool, but got int
};

// Get clear, actionable error messages:
try {
  final user = UserSafeJsonParsing.fromJsonSafe(apiResponse);
} catch (e) {
  print(e);
  /* Enhanced Output:
  ๐Ÿšจ OOPS! There's a problem with your JSON data:
  
  ๐Ÿ” EXACT PROBLEM DIAGNOSIS:
     โŒ Field 'user_id' has the wrong data type
  
  ๐Ÿ“Š TYPE COMPARISON:
     Expected: int (whole number)
     Got: String (text)
     Value: "12345"
     
  ๐Ÿ”ง How to fix this (copy-paste ready):
  1. Fix your API to return: {"user_id": 12345}
  2. Update your model: final String user_id;
  3. Add conversion: int.tryParse(json['user_id'])
  */
  
  // Now you can immediately contact the backend team with specific details!
}

Nullable Fields Made Easy #

factory User.fromJsonSafe(Map<String, dynamic> json) {
  return User(
    id: json.getSafe('id', (v) => v as int),
    name: json.getSafe('name', (v) => v as String),
    age: json.getSafe('age', (v) => v as int),
    // Optional fields with safe parsing
    email: json.getNullableSafe('email', (v) => v as String),
    phoneNumber: json.getNullableSafe('phone', (v) => v as String),
  );
}

Complex Type Parsing #

// Parse nested objects and lists safely
factory Order.fromJsonSafe(Map<String, dynamic> json) {  
  return Order(
    id: json.getSafe('id', (v) => v as String),
    items: json.getSafe('items', (v) => 
      (v as List).map((item) => OrderItem.fromJsonSafe(item)).toList()
    ),
    totalAmount: json.getSafe('total', (v) => (v as num).toDouble()),
    createdAt: json.getSafe('created_at', (v) => DateTime.parse(v as String)),
  );
}

๐Ÿ”ง Advanced Usage #

Custom Parser Functions #

// Create reusable parsers for common patterns
T parseEnum<T>(List<T> values, dynamic value) {
  final stringValue = value as String;
  return values.firstWhere(
    (e) => e.toString().split('.').last == stringValue,
    orElse: () => throw FormatException('Invalid enum value: $stringValue'),
  );
}

// Use in your models
factory UserStatus.fromJsonSafe(Map<String, dynamic> json) {
  return UserStatus(
    status: json.getSafe('status', (v) => parseEnum(StatusType.values, v)),
  );
}

Debugging Production Issues #

// Add logging to track parsing issues in production
factory User.fromJsonSafe(Map<String, dynamic> json) {
  try {
    return User(
      id: json.getSafe('id', (v) => v as int),
      name: json.getSafe('name', (v) => v as String),
      age: json.getSafe('age', (v) => v as int),
    );
  } catch (e) {
    // Log the error with full context for debugging
    FirebaseCrashlytics.instance.recordError(
      e, 
      null, 
      fatal: false,
      information: ['JSON: ${jsonEncode(json)}'],
    );
    rethrow;
  }
}

๐ŸŽจ Best Practices #

  1. Keep Both Methods: Maintain both fromJson and fromJsonSafe for backward compatibility
  2. Use in Development: Use fromJsonSafe during development and testing
  3. Production Strategy: Consider using fromJsonSafe in production for critical models
  4. Error Handling: Always wrap safe parsing in try-catch blocks
  5. Logging: Log parsing errors with full context for debugging

๐Ÿ”— Works Great With Your Stack #

Perfect integration with Dio, Retrofit, and json_annotation - use the same safe parsing methods with your existing API client setup.

๐ŸŽฎ Usage Examples #

Code Generation Example #

@JsonSerializable()
@SafeJsonParsing(
  validateRequiredKeys: true,  // Validate all keys exist first
  methodName: 'parseJsonSafe'  // Custom method name
)
class Product {
  @SafeJsonField(
    description: 'Product price in USD',
    expectedFormat: 'Positive number (e.g., 19.99)',
    commonValues: ['9.99', '19.99', '29.99'],
  )
  final double price;
  
  @JsonKey(name: 'is_available')
  final bool isAvailable;
  
  // Constructor and standard methods...
  
  // ๐Ÿš€ AUTO-GENERATED: Product.parseJsonSafe(json) with enhanced errors!
}

๐Ÿ“Ÿ CLI Command Cheat Sheet #

# Auto-annotate @JsonSerializable models with @SafeJsonParsing()
flutter pub run json_annotation_tools init

# Preview changes without writing them
flutter pub run json_annotation_tools init --dry-run

# Regenerate JSON + safe parsing code
flutter pub run build_runner build --delete-conflicting-outputs

# Optional helper to demo the enhanced error output
dart run tool/demo_safe_json_error.dart

๐Ÿ”ง Handling Errors #

  • Prefer the generated ModelSafeJsonParsing.fromJsonSafe(json) whenever you deserialize API data.
  • Catch FormatException at the repository/data-source layer and log or remap it once.
  • Fall back to manual helpers like json.getSafeInt('field') when a model cannot be annotated.
  • Use @SafeJsonConfig if you need global interception/logging without touching each call site.
try {
  final summary = DoctorSummarySafeJsonParsing.fromJsonSafe(payload);
} on FormatException catch (error) {
  logger.error('JSON mismatch: ${error.message}');
  throw DataParseFailure.fromServer(error.message);
}

๐Ÿช„ Riverpod integration #

If youโ€™re using Riverpod, wrap the async work with AsyncValue.guard (or your own helper) and convert FormatException into an app-friendly error.

final doctorSummaryProvider = FutureProvider.autoDispose((ref) async {
  final repository = ref.watch(summaryRepositoryProvider);

  return AsyncValue.guard(() async {
    final json = await repository.fetchSummaryJson();
    return DoctorSummarySafeJsonParsing.fromJsonSafe(json);
  }).when(
    data: (value) => value,
    error: (error, stack) {
      if (error is FormatException) {
        // Surface the enhanced message in your UI/logs
        ref.read(loggerProvider).warn(error.message);
        throw JsonParseFailure(error.message);
      }
      throw error;
    },
    loading: () => const AsyncLoading(),
  );
});

Youโ€™ll get Riverpodโ€™s normal AsyncError states while still benefiting from the detailed parsing message. If you want to render the detailed error in a widget (for example in a team list screen):

state.when(
  loading: () => const CircularProgressIndicator(),
  error: (error, _) {
    final message = error is FormatException
        ? error.message
        : (error.toString().isEmpty ? 'No data available!' : error.toString());
    return Center(
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Text(
          message,
          textAlign: TextAlign.center,
        ),
      ),
    );
  },
  data: (teamMembers) => ...,
);

๐Ÿ“ Complete Riverpod example #

import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:json_annotation_tools/json_annotation_tools.dart';

part 'product.g.dart';
part 'product.safe_json_parsing.g.dart';

@JsonSerializable()
@SafeJsonParsing()
class Product {
  Product({required this.id, required this.name, required this.price});

  final int id;
  final String name;
  final double price;

  factory Product.fromJson(Map<String, dynamic> json) =>
      ProductSafeJsonParsing.fromJsonSafe(json);
}

final productRepositoryProvider = Provider<ProductRepository>((ref) {
  return ProductRepository();
});

class ProductRepository {
  Future<Map<String, dynamic>> fetchProductJson() async {
    return {
      'id': 1,
      'name': 'Riverpod Coffee Mug',
      'price': '19.99', // wrong type on purpose
    };
  }
}

final productProvider = FutureProvider.autoDispose<Product>((ref) async {
  final repo = ref.watch(productRepositoryProvider);

  return AsyncValue.guard(() async {
    final json = await repo.fetchProductJson();
    return Product.fromJson(json);
  }).when(
    data: (value) => value,
    error: (error, stackTrace) {
      if (error is FormatException) {
        ref.read(loggerProvider).call(error.message);
        rethrow;
      }
      throw error;
    },
    loading: () => throw StateError('unexpected loading state'),
  );
});

final loggerProvider = Provider<void Function(String)>((ref) {
  return (message) => print('LOG: $message');
});

void main() async {
  final container = ProviderContainer();
  try {
    await container.read(productProvider.future);
  } on FormatException catch (e) {
    print('Enhanced error: ${e.message}');
  }
}

Add flutter_riverpod to your pubspec (and run build_runner to generate the part files) before running this snippet.

๐Ÿงช Testing & Debugging #

  • flutter test test/safe_json_parsing_test.dart โ€“ regression test that asserts on the enhanced message.
  • dart run tool/demo_safe_json_error.dart โ€“ prints the full diagnostic for a controlled payload.
  • rg "SafeJsonParsing" -g"*.g.dart" โ€“ quick audit to check which models already have safe parsers.
  • Consider golden tests around high-value endpoints to lock in the detailed error copy.

๐Ÿค Migration Guide #

From Standard JSON Serialization #

  1. Keep existing code working: Your current fromJson methods continue to work
  2. Add safe alternatives: Create fromJsonSafe methods alongside existing ones
  3. Test thoroughly: Use fromJsonSafe in tests to catch issues early
  4. Gradual adoption: Migrate critical models first, then expand usage

๐Ÿ“Š Performance Impact #

  • Zero overhead during successful parsing
  • Minimal impact during errors (only when you need the debugging info)
  • Same memory usage as standard parsing
  • Compatible with all existing JSON serialization patterns

๐ŸŒ Platform Support #

This package works seamlessly across all Flutter/Dart platforms:

โœ… Fully Supported Platforms: #

  • ๐Ÿ“ฑ iOS: Native iOS apps (iPhone/iPad)
  • ๐Ÿค– Android: Native Android apps (phones/tablets)
  • ๐ŸŒ Web: Progressive Web Apps (PWA) and web browsers
  • ๐Ÿ’ป macOS: Native desktop apps
  • ๐ŸชŸ Windows: Native desktop apps
  • ๐Ÿง Linux: Native desktop apps

๐Ÿ“ฆ Package Type: #

  • Pure Dart package - no platform-specific code
  • No native dependencies - works everywhere Flutter works
  • Same API across all platforms
  • Consistent behavior regardless of target platform

๐ŸŽฎ Try the Demo: #

Run our interactive example app to test on your preferred platform:

# iOS (requires Xcode and iOS Simulator/Device)
cd example_app && flutter run -d ios

# Android (requires Android SDK and Emulator/Device)  
cd example_app && flutter run -d android

# Web (opens in default browser)
cd example_app && flutter run -d chrome

# macOS (requires macOS development setup)
cd example_app && flutter run -d macos

# Windows (requires Windows development setup)
cd example_app && flutter run -d windows

# Linux (requires Linux development setup)
cd example_app && flutter run -d linux

# Generate a static web build ready for hosting (Netlify/GitHub Pages/etc.)
cd example_app && flutter build web --release

๐Ÿ› Troubleshooting #

Common Issues #

Q: "I'm getting errors about missing keys"

// Use getNullableSafe for optional fields
email: json.getNullableSafe('email', (v) => v as String),

Q: "How do I handle nested objects?"

// Parse nested objects recursively
address: json.getSafe('address', (v) => Address.fromJsonSafe(v as Map<String, dynamic>)),

Q: "Can I use this with existing json_serializable models?"

// Yes! Add safe methods alongside generated ones
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json); // Generated
factory User.fromJsonSafe(Map<String, dynamic> json) { /* Your safe implementation */ }

๐Ÿค Contributing #

We welcome contributions! Here's how to get involved:

๐Ÿ› Report Issues: #

Found a bug or have a feature request?

๐Ÿ’ก Contribute Code: #

  1. Fork the repository: https://github.com/khokanuzzaman/json_annotation_tools
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Commit your changes: git commit -m 'Add amazing feature'
  4. Push to branch: git push origin feature/amazing-feature
  5. Open a Pull Request

๐Ÿ“– Improve Documentation: #

  • Fix typos or unclear explanations
  • Add more examples or use cases
  • Enhance visual documentation

๐Ÿงช Add Tests: #

  • Write tests for new features
  • Improve existing test coverage
  • Add edge case testing

Please see our Contributing Guide for detailed guidelines.

๐Ÿ“„ License #

This project is licensed under the MIT License - see the LICENSE file for details.

๐Ÿ™ Acknowledgments #

  • Built to complement the excellent json_annotation and json_serializable packages
  • Inspired by the need for better JSON debugging in Flutter development
  • Thanks to the Flutter community for feedback and suggestions

Made with โค๏ธ for the Flutter community

Stop debugging JSON parsing errors in the dark - see exactly what's wrong and fix it fast!

2
likes
140
points
54
downloads

Publisher

verified publisherkhokan.me

Weekly Downloads

Transform cryptic JSON parsing errors into crystal-clear, actionable error messages. Perfect companion to json_annotation.

Documentation

API reference

License

MIT (license)

Dependencies

analyzer, args, build, flutter, json_annotation, meta, path, source_gen

More

Packages that depend on json_annotation_tools