flutter-implement-json-serialization — Claude Code skill
Teaches coding agents to build Dart models with fromJson and toJson methods using dart:convert. Useful for manual JSON mapping in simple Flutter data structures.
npx skills add flutter/agent-plugins --skill flutter-implement-json-serialization -a claude-codeWhat flutter-implement-json-serialization does
The skill outlines standard workflows for manual JSON serialization in Flutter without code generation packages. It guides the agent to define models with final fields, a factory Model.fromJson(Map<String, dynamic> json) constructor using explicit casting or pattern matching, and a Map<String, dynamic> toJson() method.
For network responses via the http package, the skill enforces distinct parsing strategies. Small payloads run synchronously on the main thread. If JSON processing takes longer than 16ms or handles arrays of thousands of records, it offloads decoding to a separate isolate using compute() to prevent frame drops.
The checklist explicitly forbids returning null on failed HTTP status codes, requiring an explicit Exception instead.
What it helps with
- write Flutter model classes with manual
fromJsonandtoJsonmethods - cast dynamic decoding results safely into
Map<String, dynamic> - offload parsing of massive JSON payloads into background isolates using
compute() - handle HTTP responses with explicit exceptions on non-200 status codes
Example prompts for the agent
- Create a User model with manual fromJson and toJson using dart:convert
- Implement fetchUsers with compute() to parse a large JSON array in the background
- Add pattern matching deserialization to this Dart class
How to install flutter-implement-json-serialization
1Skills CLI (Vercel)
npx skills add flutter/agent-plugins --skill flutter-implement-json-serialization -a claude-code2Manually: put the files in place
~/.claude/skills/flutter-implement-json-serialization/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/flutter-implement-json-serialization/
1Skills CLI (Vercel)
npx skills add flutter/agent-plugins --skill flutter-implement-json-serialization -a codex2Manually: put the files in place
.agents/skills/flutter-implement-json-serialization/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add flutter/agent-plugins --skill flutter-implement-json-serialization -a cursor2Manually: put the files in place
.cursor/skills/flutter-implement-json-serialization/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install flutter/agent-plugins flutter-implement-json-serialization2Manually: put the files in place
.github/skills/flutter-implement-json-serialization/SKILL.md1Skills CLI (Vercel)
npx skills add flutter/agent-plugins --skill flutter-implement-json-serialization -a gemini-cli2Platform CLI
gemini skills install https://github.com/flutter/agent-plugins --path skills/flutter-implement-json-serializationManually: put the files in place
.devin/skills/flutter-implement-json-serialization/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add flutter/agent-plugins --skill flutter-implement-json-serialization -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
From the same set7
The whole set →Similar
Questions about flutter-implement-json-serialization
How to install flutter-implement-json-serialization in Claude Code?
Run npx skills add flutter/agent-plugins --skill flutter-implement-json-serialization -a claude-code.
What does flutter-implement-json-serialization do?
It provides clear rules for manual Dart model serialization using dart:convert, strict type casting, unit tests, and background isolate parsing.
When does the skill require using compute()?
It requires compute() whenever parsing large payloads, such as thousands of objects, or when decoding time exceeds 16ms to avoid UI stutter.
Source text
SKILL.md · BSD-3-Clause
---
name: flutter-implement-json-serialization
description: Create model classes with `fromJson` and `toJson` methods using `dart:convert`. Use when manually mapping JSON keys to class properties for simple data structures.
metadata:
model: models/gemini-3.1-pro-preview
last_modified: Tue, 21 Apr 2026 21:44:50 GMT
---
# Serializing JSON Manually in Flutter
## Contents
- [Core Guidelines](#core-guidelines)
- [Workflow: Implementing a Serializable Model](#workflow-implementing-a-serializable-model)
- [Workflow: Fetching and Parsing JSON](#workflow-fetching-and-parsing-json)
- [Examples](#examples)
## Core Guidelines
- **Import `dart:convert`**: Utilize Flutter's built-in `dart:convert` library for manual JSON encoding (`jsonEncode`) and decoding (`jsonDecode`).
- **Enforce Type Safety**: Always cast the `dynamic` result of `jsonDecode()` to the expected type, typically `Map<String, dynamic>` for objects or `List<dynamic>` for arrays.
- **Encapsulate Serialization Logic**: Define plain model classes containing properties corresponding to the JSON structure. Implement a `fromJson` factory constructor and a `toJson` method within the model.
- **Handle Background Parsing**: If parsing large JSON documents (execution time > 16ms), offload the parsing logic to a separate isolate using Flutter's `compute()` function to prevent UI jank.
- **Throw Exceptions on Failure**: When handling HTTP responses, throw an exception if the status code is not successful (e.g., not 200 OK or 201 Created). Do not return `null`.
## Workflow: Implementing a Serializable Model
Use this checklist to implement manual JSON serialization for a data model.
**Task Progress:**
- [ ] Define the plain model class with `final` properties.
- [ ] Implement the `factory Model.fromJson(Map<String, dynamic> json)` constructor.
- [ ] Implement the `Map<String, dynamic> toJson()` method.
- [ ] Write unit tests for both serialization methods.
- [ ] Run validator -> review type mismatch errors -> fix casting logic.
1. **Define the Model**: Create a class with properties matching the JSON keys.
2. **Implement `fromJson`**: Extract values from the `Map` and cast them to the appropriate Dart types. Use pattern matching or explicit casting.
3. **Implement `toJson`**: Return a `Map<String, dynamic>` mapping the class properties back to their JSON string keys.
4. **Validate**: Execute unit tests to ensure type safety, autocompletion, and compile-time exception handling function correctly.
## Workflow: Fetching and Parsing JSON
Use this conditional workflow when retrieving and parsing JSON from a network request.
**Task Progress:**
- [ ] Execute the HTTP request.
- [ ] Validate the response status code.
- [ ] Determine parsing strategy (Synchronous vs. Isolate).
- [ ] Decode and map the JSON to the model.
1. **Execute Request**: Use the `http` package to perform the network call.
2. **Validate Response**:
- If `response.statusCode == 200` (or 201 for POST), proceed to parsing.
- If the status code indicates failure, throw an `Exception`.
3. **Determine Parsing Strategy**:
- If parsing a **small payload** (e.g., a single object), parse synchronously on the main thread.
- If parsing a **large payload** (e.g., an array of thousands of objects), use `compute(parseFunction, response.body)` to parse in a background isolate.
4. **Decode and Map**: Pass the decoded JSON to your model's `fromJson` constructor.
## Examples
### High-Fidelity Model Implementation
```dart
import 'dart:convert';
class User {
final int id;
final String name;
final String email;
const User({
required this.id,
required this.name,
required this.email,
});
// Factory constructor for deserialization
factory User.fromJson(Map<String, dynamic> json) {
return switch (json) {
{
'id': int id,
'name': String name,
'email': String email,
} =>
User(
id: id,
name: name,
email: email,
),
_ => throw const FormatException('Failed to load User.'),
};
}
// Method for serialization
Map<String, dynamic> toJson() {
return {
'id': id,
'name': name,
'email': email,
};
}
}
```
### Synchronous Parsing (Small Payload)
```dart
import 'dart:convert';
import 'package:http/http.dart' as http;
Future<User> fetchUser(http.Client client, int userId) async {
final response = await client.get(
Uri.parse('https://api.example.com/users/$userId'),
headers: {'Accept': 'application/json'},
);
if (response.statusCode == 200) {
// Decode returns dynamic, cast to Map<String, dynamic>
final Map<String, dynamic> jsonMap = jsonDecode(response.body) as Map<String, dynamic>;
return User.fromJson(jsonMap);
} else {
throw Exception('Failed to load user');
}
}
```
### Background Parsing (Large Payload)
```dart
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
// Top-level function required for compute()
List<User> parseUsers(String responseBody) {
final parsed = (jsonDecode(responseBody) as List<dynamic>).cast<Map<String, dynamic>>();
return parsed.map<User>((json) => User.fromJson(json)).toList();
}
Future<List<User>> fetchUsers(http.Client client) async {
final response = await client.get(
Uri.parse('https://api.example.com/users'),
headers: {'Accept': 'application/json'},
);
if (response.statusCode == 200) {
// Offload expensive parsing to a background isolate
return compute(parseUsers, response.body);
} else {
throw Exception('Failed to load users');
}
}
```
© flutter · BSD-3-Clause · flutter/agent-plugins