Agent skill

Squadron Marshaling

by d-markey in d-markey/squadron

A skill your agent uses when handling custom classes, object serialization, deserialization, and custom marshalers (SquadronMarshaler, GenericMarshaler, MarshalingContext) for cross-platform worker…

MITAuto-check passedMobile

Install Squadron Marshaling

skills CLI
$ npx skills add d-markey/squadron --skill squadron-marshaling -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install d-markey/squadron squadron-marshaling --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/d-markey/squadron.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/squadron-marshaling .claude/skills/squadron-marshaling && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
squadron-marshaling
GitHub stars
138
Token cost
~2.6k tokens
SKILL.md length
833 words
Files
1
Skills in repo
3
Repo updated
First seen
Licence
MIT

At a glance

A skill your agent uses when handling custom classes, object serialization, deserialization, and custom marshalers (SquadronMarshaler, GenericMarshaler, MarshalingContext) for cross-platform worker…

  • Works in 6 steps: Cross-Platform Constraints &… → Approach A: Direct Serialization in… → Approach B: Dedicated Marshalers via the… → …
  • Handling custom classes
  • SKILL.md covers 1. Cross-Platform Constraints…, 2. Approach A: Direct…, 3. Approach B: Dedicated… and 4. Alternative Optimization:…, plus 2 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

Squadron Marshaling is an agent skill from d-markey/squadron. Use when handling custom classes, object serialization, deserialization, and custom marshalers (SquadronMarshaler, GenericMarshaler, MarshalingContext) for cross-platform worker communication in Squadron.

Its SKILL.md is about 2.6k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Mobile. It works with Dart. The repository describes itself as: Multithreading and worker thread pool for Dart / Flutter, to offload CPU-bound and heavy I/O tasks to Isolate or Web Worker threads (JS+WASM). The licence is MIT.

When your agent uses it

  • Handling custom classes
  • Object serialization
  • Deserialization
  • Custom marshalers (SquadronMarshaler

Example prompts

  • “/squadron-marshaling”

Workflow steps

6 steps, taken from the step headings in SKILL.md.

  1. Cross-Platform Constraints & Serialization Approaches
  2. Approach A: Direct Serialization in Custom Classes
  3. Approach B: Dedicated Marshalers via the SquadronMarshaler Interface
  4. Alternative Optimization: Extension Types over List or Map
  5. Performance Optimization: Platform-Specific Marshalers
  6. Registering Marshalers (@SquadronMethod & @MyCustomTypeMarshaler)

What it can do on your machine

Read from SKILL.md and the folder at commit 4ab7f15. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are dart).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Squadron Marshaling loads about 2.6k tokens when it runs. Until then it costs about 56 tokens; SKILL.md has 833 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~56
When it runs · the whole SKILL.md, loaded when a task matches
~2.6k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from d-markey/squadron at commit 4ab7f15, republished under its MIT licence (© d-markey). 833 words, ~2,648 tokens.

Download SKILL.mdSave it as .claude/skills/squadron-marshaling/SKILL.md (or your agent's skills folder).
name
squadron-marshaling
description
Use when handling custom classes, object serialization, deserialization, and custom marshalers (SquadronMarshaler, GenericMarshaler, MarshalingContext) for cross-platform worker communication in Squadron.

Squadron Custom Class Marshaling Guide

In Squadron, passing base types (int, double, String, bool, null, nullable variants, List, Map) between the main thread and worker threads is handled automatically. However, passing custom classes requires serialization/deserialization because thread boundaries (isolates on Native, Web Workers on Web) do not share memory.

Note on Spelling: While British English uses marshalling (two 'l's), American English uses marshaling (one 'l'). Squadron follows the American spelling and uses SquadronMarshaler (one 'l') in its class names.

1. Cross-Platform Constraints & Serialization Approaches

  • Native (VM / Isolates): On the VM, marshaling is generally avoidable. Dart's Isolate send ports handle many custom object graphs natively via underlying VM serialization/copying.
  • Web (Web Workers): Marshaling becomes mandatory and critical on the Web (and even more so in cross-platform code supporting both Web and VM). Web Workers operate over message channels using strict structured cloning where complex custom classes cannot be sent directly unless converted into transferable primitives (like List, Map, or JSArrayBuffer).

When passing custom classes across thread boundaries, Squadron provides two primary ways to handle serialization:

  • Approach A: Implement serialization directly within the custom class (via marshal() / unmarshal() or standard toJson() / fromJson()).
  • Approach B: Implement a dedicated marshaler class via the SquadronMarshaler interface. Note that marshaler classes are used as annotations (for service method arguments/return types or on the custom class itself), and as a result must provide const constructors and be instantiable as const instances.

2. Approach A: Direct Serialization in Custom Classes

You can implement serialization directly within your custom class without writing a separate marshaler class:

  • Dedicated methods: Implement an instance method SomeTransferable marshal({MarshalingContext? context}) and a factory constructor or static method static MyCustomType unmarshal(SomeTransferable transferable, {MarshalingContext? context}).
  • Standard JSON methods: squadron_builder can also automatically detect and use standard toJson() and fromJson() methods when present. (Note: The JSON approach is simple and straightforward, but does not support a MarshalingContext, meaning it cannot handle circular references or object identity preservation across complex object graphs).
Example: Direct marshal() & unmarshal()
dart
import 'package:squadron/squadron.dart';

class TaskItem {
  final String id;
  final String description;

  TaskItem(this.id, this.description);

  // Serialize to a transferable List or Map
  List marshal({MarshalingContext? context}) {
    return [id, description];
  }

  // Deserialize back from the transferable representation
  static TaskItem unmarshal(dynamic transferable, {MarshalingContext? context}) {
    final list = transferable as List;
    return TaskItem(list[0] as String, list[1] as String);
  }
}
Example: Standard toJson() & fromJson()
dart
class TaskItemJson {
  final String id;
  final String description;

  TaskItemJson(this.id, this.description);

  Map<String, dynamic> toJson() => {
        'id': id,
        'description': description,
      };

  factory TaskItemJson.fromJson(Map<String, dynamic> json) =>
      TaskItemJson(json['id'] as String, json['description'] as String);
}

3. Approach B: Dedicated Marshalers via the SquadronMarshaler Interface

For cleaner separation of concerns, you can implement a separate marshaler class using the SquadronMarshaler interface (GenericMarshaler & MarshalingContext). Because these dedicated marshaler classes are used as annotations (e.g., @PersonMarshaler()), they must have a const constructor and be usable as const instances.

To send custom classes across threads via a separate marshaler, implement SquadronMarshaler<T, S>:

  • T: The original custom class type.
  • S: The transferable / serializable representation type (typically List or Map).
dart
abstract class SquadronMarshaler<T, S> {
  const SquadronMarshaler();

  S marshal(T data, [MarshalingContext? context]);
  T unmarshal(S data, [MarshalingContext? context]);
}

Rule: unmarshal(marshal(data)) must produce an instance of T equivalent to the original data.

  • Important Equivalence Note: Because marshaling and unmarshaling create a brand-new instance across the thread boundary, identical(original, unmarshaled) will always return false, and the equality operator (==) will return false unless explicitly overloaded in your class T.
Using GenericMarshaler & MarshalingContext

For complex object graphs, deep structures, or circular references, Squadron provides GenericMarshaler and MarshalingContext.

  • MarshalingContext: Tracks object references during serialization and deserialization to prevent infinite loops (e.g., circular graphs or shared references) and preserve object identity within the same payload transfer.
Example Marshaling Implementation:
dart
part of 'person.dart';

class PersonMarshaler extends GenericMarshaler<Person> {
  const PersonMarshaler();

  @override
  dynamic marshal(Person data, [MarshalingContext? context]) {
    var res = context?.getReference<List>(data);
    if (res != null) return res;

    res = [
      data.lastName,
      data.firstName,
      data.dateOfBirth,
    ];

    // Register reference before recursing to handle circular references
    context?.setReference(data, res);

    return res;
  }

  @override
  Person unmarshal(dynamic data, [MarshalingContext? context]) {
    data as List;
    var res = context?.getReference<Person>(data);
    if (res != null) return res;

    res = Person._(data[0], data[1], data[2]);
    context?.setReference(data, res);

    return res;
  }
}

Show full SKILL.md (374 more words)Show less

4. Alternative Optimization: Extension Types over List or Map

To completely avoid the cost and complexity of writing custom marshalers for custom data structures, you can implement business objects as Dart extension types wrapping a List or Map.

Because extension types are statically erased at runtime back to their underlying representation (List or Map), they are passed across thread boundaries natively without needing any serialization or custom marshaler.

Example Extension Type (person_ex.dart):
dart
extension type PersonEx(Map<String, dynamic> _data) {
  PersonEx({required String lastName, required String firstName, int? age})
      : this({'lastName': lastName, 'firstName': firstName, 'age': age});

  String get lastName => _data['lastName'] as String;
  String get firstName => _data['firstName'] as String;
  int? get age => _data['age'] as int?;
}

Note: Do not implement or implement-forward the underlying Map (e.g., omit implements Map<String, dynamic>), as doing so would expose raw map mutation methods that could violate object immutability (e.g., allowing unintended writes to keys).

Trade-offs & Limitations:
  • Pros: Zero runtime overhead for marshaling; works seamlessly across all platforms out-of-the-box as a standard Map.
  • Cons / Costs:
    • Minor performance overhead when accessing members (dictionary lookups / key checks in the underlying Map).
    • Extension types do not support traditional class inheritance trees or polymorphism.
    • Cannot override == or hashCode in extension types (value equality must be handled via helper functions or property comparisons).

5. Performance Optimization: Platform-Specific Marshalers

Because Native (VM) isolates can natively pass and copy many object types while Web Workers require strict serialization, you can optimize performance by implementing platform-specific marshalers:

  • Use GenericMarshaler<T> (or a custom serializer) on Web.
  • Use IdentityMarshaler<T> on the VM/Native platform (which passes objects directly with zero overhead).

You can export or alias the correct marshaler conditionally using Dart's export ... if (dart.library.js_interop) ...:

Example Conditional Marshaler Export (person_marshaler.dart):
dart
export 'person_marshaler_stub.dart'
    if (dart.library.io) 'person_marshaler_vm.dart'
    if (dart.library.js_interop) 'person_marshaler_web.dart';
  • person_marshaler_stub.dart (fallback / analyzer stub):

    dart
    import 'package:squadron/squadron.dart';
    import 'person.dart';
    
    abstract class PersonMarshaler implements SquadronMarshaler<Person, dynamic> {
      const PersonMarshaler();
    }
  • person_marshaler_vm.dart (Native / VM platform):

    dart
    import 'package:squadron/squadron.dart';
    import 'person.dart';
    
    // Zero-overhead identity marshaler on VM
    typedef PersonMarshaler = IdentityMarshaler<Person>;
  • person_marshaler_web.dart (Web platform):

    dart
    import 'package:squadron/squadron.dart';
    import 'person.dart';
    
    // Full serialization marshaler on Web
    class PersonMarshaler extends GenericMarshaler<Person> {
      const PersonMarshaler();
      // ... marshal / unmarshal implementations for Web ...
    }

6. Registering Marshalers (@SquadronMethod & @MyCustomTypeMarshaler)

To instruct squadron_builder to marshal custom parameters or return types, MyCustomType parameters must be decorated with a marshaler (ensuring marshalers provide a const constructor and can be instantiated as const instances):

dart
@SquadronMethod()
@PersonMarshaler()
Future<Person> processPerson(@PersonMarshaler() Person person) async {
  // ...
}

Alternative (Global Registration): Instead of decorating parameters individually on every method, you can decorate the custom class itself with its marshaler. When decorated this way, squadron_builder automatically uses the registered marshaler everywhere the custom type is required across service methods:

dart
@PersonMarshaler()
class Person {
  // ...
}

@SquadronService()
class MyService {
  @SquadronMethod()
  Future<Person> processPerson(Person person) async {
    // Automatically uses PersonMarshaler
    return person;
  }
}

© d-markey, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in skills/squadron-marshaling of d-markey/squadron.

Open the folder on GitHubat commit 4ab7f15

Compare with similar skills

Squadron Marshaling next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Squadron Marshaling compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Squadron Marshaling this skilld-markey/squadron138—~2.6kAutomated safety check: PassMIT
Fjson Dart Bean GeneratorK3vinb5/unyo-app662—~2.2kAutomated safety check: PassBSD-3-Clause
Flutter Riverpod State Managementandrewyng/context-hub14k—~1.1kAutomated safety check: PassMIT
BlocVeryGoodOpenSource/vgv-ai-flutter-plugin170—~2kAutomated safety check: PassMIT
Dart Best Practiceskevmoo/dash_skills147—~709Automated safety check: PassApache-2.0
Build Runnerbrim-borium/spotify_sdk166—~195Automated safety check: PassApache-2.0

Similar skills

  • Generate Dart bean classes from JSON and regenerate serialization helpers using the fjson CLI.

    662 GitHub stars~2.2k tokensUpdated 3 mo ago
    MobileAuto-check passed
  • Guides Flutter state management with Riverpod: choosing provider types, wiring ConsumerWidgets, handling async state and lifecycle, and overriding providers in tests.

    14k GitHub stars~1.1k tokensUpdated 4 mo ago
    MobileAuto-check passed
  • Bloc

    VeryGoodOpenSource/vgv-ai-flutter-plugin

    Best practices for Bloc state management in Flutter/Dart, covering Cubit versus Bloc, event and state naming, sealed classes with Equatable, the Page/View split with BlocProvider, BlocBuilder…

    170 GitHub stars~2k tokensUpdated 3 days ago
    MobileAuto-check passed
  • Dart Best Practices

    kevmoo/dash_skills

    General best practices for Dart development. An agent skill from kevmoo/dash_skills.

    147 GitHub stars~709 tokensUpdated today
    MobileAuto-check passed
  • Build Runner

    brim-borium/spotify_sdk

    Generate Dart JSON models and .g.dart files using buildrunner.

    166 GitHub stars~195 tokensUpdated today
    MobileAuto-check passed
  • Dart Doc Validation

    kevmoo/dash_skills

    Best practices for validating Dart documentation comments. An agent skill from kevmoo/dash_skills.

    147 GitHub stars~822 tokensUpdated today
    MobileAuto-check passed

More from d-markey/squadron

  • Squadron Cancelation

    d-markey/squadron

    A skill your agent uses when implementing task cancelation, handling CancelationToken, propagating cancelation signals across thread/worker boundaries, and dealing with synchronous vs.

    138 GitHub stars~922 tokensUpdated 16 days ago
    Auto-check passed
  • Squadron Worker

    d-markey/squadron

    A skill your agent uses when building, writing, or refactoring Squadron workers, worker pools, worker services, or using squadronbuilder annotations (@SquadronService, @SquadronMethod) for…

    138 GitHub stars~1.6k tokensUpdated 16 days ago
    Auto-check passed

Works with

Categories

Questions about Squadron Marshaling

What does Squadron Marshaling do?

A skill your agent uses when handling custom classes, object serialization, deserialization, and custom marshalers (SquadronMarshaler, GenericMarshaler, MarshalingContext) for cross-platform worker…. Squadron Marshaling is an agent skill from d-markey/squadron. Use when handling custom classes, object serialization, deserialization, and custom marshalers (SquadronMarshaler, GenericMarshaler, MarshalingContext) for cross-platform worker communication in Squadron.

When should I use Squadron Marshaling?

Squadron Marshaling fits situations like: handling custom classes; object serialization; deserialization; custom marshalers (SquadronMarshaler.

How do I install Squadron Marshaling in Claude Code?

Run `npx skills add d-markey/squadron --skill squadron-marshaling -a claude-code`. Or copy the skill folder (skills/squadron-marshaling in d-markey/squadron) into .claude/skills/squadron-marshaling in your project. Claude Code loads it when a task matches its description.

How do I install Squadron Marshaling in Codex?

Run `npx skills add d-markey/squadron --skill squadron-marshaling -a codex`. Or copy the skill folder (skills/squadron-marshaling in d-markey/squadron) into .agents/skills/squadron-marshaling in your project. Codex loads it when a task matches its description.

Can I use Squadron Marshaling in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add d-markey/squadron --skill squadron-marshaling -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/squadron-marshaling, .gemini/skills/squadron-marshaling, .github/skills/squadron-marshaling and .opencode/skills/squadron-marshaling in your project.

What does Squadron Marshaling need to run?

SKILL.md names no scripts, command-line tools or credentials: Squadron Marshaling is instructions for the agent only.

Does Squadron Marshaling access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Squadron Marshaling safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Squadron Marshaling use?

Squadron Marshaling is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Squadron Marshaling use?

About 2.6k tokens (SKILL.md is roughly 11k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Squadron Marshaling?

Skills that share tags, products or a category with Squadron Marshaling: Fjson Dart Bean Generator (K3vinb5/unyo-app, 662 stars), Flutter Riverpod State Management (andrewyng/context-hub, 14k stars), Bloc (VeryGoodOpenSource/vgv-ai-flutter-plugin, 170 stars) and Dart Best Practices (kevmoo/dash_skills, 147 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Squadron Marshaling?

d-markey (a GitHub user) maintains it in d-markey/squadron, which has 138 GitHub stars. The repository holds 3 skills in this directory. The repository was last updated on September 22, 2026.

Source: d-markey/squadron on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.