{"id":"115117f0-e843-420b-80ae-f2087146609a","shortId":"JuYZYp","kind":"skill","title":"msgspec","tagline":"Auto-activate for msgspec imports, msgspec.Struct, msgspec.Meta, msgspec.json, msgspec.msgpack, tagged unions, enc_hook, dec_hook, or convert(). Use when defining msgspec models, serialization codecs, validation constraints, discriminated unions, or Litestar DTO data shapes. Not ","description":"# msgspec Skill\n\nmsgspec is a high-performance Python library for serialization, deserialization, and validation. Structs are ~5x more memory-efficient than regular classes and serialize faster than Pydantic or dataclasses.\n\n## Code Style Rules\n\n- Use PEP 604 for unions: `T | None` (not `Optional[T]`)\n- **`from __future__ import annotations` rule** — Modules that **define** `msgspec.Struct` subclasses (library-like — runtime introspected) must NOT use `from __future__ import annotations`. Consumer modules that only *use* Structs (handlers, services, tests) MAY and typically SHOULD use it. Canonical Litestar apps use future annotations in 100+ consumer files without breaking msgspec.\n- Always annotate all fields; msgspec requires type annotations\n- Use `kw_only=True` for Structs with more than 2 fields\n\n## Quick Reference\n\n### Struct Definition\n\n```python\nimport msgspec\n\n# Basic struct\nclass User(msgspec.Struct):\n    id: int\n    name: str\n    email: str | None = None\n\n# Performance options\nclass Event(msgspec.Struct, frozen=True, gc=False):\n    \"\"\"frozen=True: immutable + hashable. gc=False: skip GC for short-lived objects.\"\"\"\n    event_type: str\n    payload: dict[str, object]\n\n# Keyword-only (recommended for >2 fields)\nclass Config(msgspec.Struct, kw_only=True):\n    host: str\n    port: int = 5432\n    ssl: bool = False\n\n# Array-like encoding (tuple encoding, more compact)\nclass Point(msgspec.Struct, array_like=True):\n    x: float\n    y: float\n\n# Rename fields for serialization\nclass ApiResponse(msgspec.Struct, rename=\"camel\"):\n    user_id: int         # serialized as \"userId\"\n    created_at: str      # serialized as \"createdAt\"\n\n# Reject unknown fields at API boundaries\nclass StrictInput(msgspec.Struct, forbid_unknown_fields=True):\n    name: str\n    value: int\n```\n\n### Validation Constraints\n\n```python\nfrom typing import Annotated\nimport msgspec\nfrom msgspec import Meta\n\nclass Product(msgspec.Struct):\n    name: Annotated[str, Meta(min_length=1, max_length=100)]\n    price: Annotated[float, Meta(gt=0)]\n    quantity: Annotated[int, Meta(ge=0, le=10_000)]\n    sku: Annotated[str, Meta(pattern=r\"^[A-Z]{2}-\\d{4}$\")]\n    weight_kg: Annotated[float, Meta(multiple_of=0.001)]\n\n# Reusable constraint aliases\nPositiveInt = Annotated[int, Meta(gt=0)]\nNonEmptyStr = Annotated[str, Meta(min_length=1)]\nPercentage = Annotated[float, Meta(ge=0.0, le=100.0)]\n\nclass Order(msgspec.Struct):\n    id: PositiveInt\n    label: NonEmptyStr\n    discount: Percentage = 0.0\n```\n\n### Serialization\n\n```python\nimport msgspec\n\n# JSON -- singleton encoder/decoder (cache these!)\nencoder = msgspec.json.Encoder()\ndecoder = msgspec.json.Decoder(User)\n\ndata = encoder.encode(user)          # bytes\nuser = decoder.decode(b'{\"id\":1,\"name\":\"Alice\"}')\n\n# Functional API (convenience, slightly slower)\ndata = msgspec.json.encode(user)\nuser = msgspec.json.decode(b'...', type=User)\n\n# MessagePack (binary, more compact)\ndata = msgspec.msgpack.encode(user)\nuser = msgspec.msgpack.decode(data, type=User)\n\n# Custom hooks for non-native types (datetime, UUID, Decimal)\nfrom datetime import datetime\nimport uuid\n\ndef enc_hook(obj: object) -> object:\n    if isinstance(obj, datetime):\n        return obj.isoformat()\n    if isinstance(obj, uuid.UUID):\n        return str(obj)\n    raise TypeError(f\"Unsupported type: {type(obj)}\")\n\ndef dec_hook(type: type, obj: object) -> object:\n    if type is datetime:\n        return datetime.fromisoformat(obj)\n    if type is uuid.UUID:\n        return uuid.UUID(obj)\n    raise TypeError(f\"Unsupported type: {type}\")\n\nencoder = msgspec.json.Encoder(enc_hook=enc_hook)\ndecoder = msgspec.json.Decoder(MyStruct, dec_hook=dec_hook)\n```\n\n### Canonical Litestar serializers (match-your-stack)\n\nLitestar apps typically need `to_json(value, as_bytes=True)` that handles UUID / datetime / Enum / Decimal for Channels broadcasts, log contexts, and JSONB writes. Pick the branch that matches your project.\n\n**Branch A — sqlspec is in-stack.** Re-export sqlspec's serializer; it already installs an `enc_hook` covering UUID, datetime, Enum, Decimal, Pydantic, dataclasses, attrs, and msgspec.Struct.\n\n```python\n# myapp/utils/serialization.py\nfrom sqlspec.utils.serializers import from_json, to_json\n\n__all__ = (\"from_json\", \"to_json\")\n```\n\nUsage:\n\n```python\nfrom myapp.utils.serialization import to_json\n\npayload = to_json(order, as_bytes=True)\nawait backend.publish(payload, channels=[f\"orders:{order.id}:events\"])\n```\n\n**Branch B — sqlspec is not in-stack.** Hand-roll an `Encoder` with an `enc_hook`.\n\n```python\n# myapp/utils/serialization.py\nimport datetime as _dt\nimport json\nfrom typing import Any\nfrom uuid import UUID\n\nimport msgspec\n\n\ndef _default(value: Any) -> str:\n    if isinstance(value, UUID):\n        return str(value)\n    if isinstance(value, _dt.datetime):\n        return value.astimezone(_dt.UTC).strftime(\"%Y-%m-%dT%H:%M:%SZ\")\n    if isinstance(value, _dt.date):\n        return value.isoformat()\n    return str(value)\n\n\n_encoder = msgspec.json.Encoder(enc_hook=_default)\n\n\ndef to_json(value: Any) -> bytes:\n    if isinstance(value, bytes):\n        return value\n    return _encoder.encode(value)\n```\n\n### Type Coercion with convert()\n\n```python\nimport msgspec\n\nraw = {\"id\": \"42\", \"name\": \"Alice\"}  # id is a string\n\n# Strict mode (default): raises on type mismatch\nuser = msgspec.convert(raw, User)  # ValidationError: id must be int\n\n# Lax mode: coerces compatible types\nuser = msgspec.convert(raw, User, strict=False)  # id coerced to 42\n\n# str_keys: dict keys are strings (useful for JSON-loaded dicts)\ndata = {\"1\": \"Alice\", \"2\": \"Bob\"}\nresult = msgspec.convert(data, dict[int, str], str_keys=True)\n\n# Convert with dec_hook for custom types\nuser = msgspec.convert(raw, UserWithUUID, dec_hook=dec_hook)\n\n# Convert dataclass/dict/object to Struct\nfrom dataclasses import dataclass\n\n@dataclass\nclass LegacyUser:\n    id: int\n    name: str\n\nlegacy = LegacyUser(id=1, name=\"Alice\")\nuser = msgspec.convert(msgspec.structs.asdict(legacy), User)\n# Or directly:\nuser = msgspec.convert(legacy, User)\n```\n\n### Dynamic Struct Creation\n\n```python\nimport msgspec\n\n# Runtime struct from field definitions\nfields = [\n    (\"id\", int),\n    (\"name\", str),\n    (\"score\", Annotated[float, Meta(ge=0.0)]),\n]\nDynamicModel = msgspec.defstruct(\"DynamicModel\", fields, kw_only=True)\n\n# With defaults\nfields_with_defaults = [\n    (\"id\", int),\n    (\"active\", bool, True),   # (name, type, default)\n]\nFlexModel = msgspec.defstruct(\"FlexModel\", fields_with_defaults)\n```\n\n### Tagged Unions (Discriminated Unions)\n\n```python\nimport msgspec\nfrom typing import Literal\n\n# Default tag field is \"type\", tag value is the class name\nclass Dog(msgspec.Struct, tag=True):\n    name: str\n    breed: str\n\nclass Cat(msgspec.Struct, tag=True):\n    name: str\n    indoor: bool\n\nAnimal = Dog | Cat\n\n# Deserialize: inspects \"type\" field to pick correct class\nanimal = msgspec.json.decode(b'{\"type\":\"Dog\",\"name\":\"Rex\",\"breed\":\"Lab\"}', type=Animal)\n\n# Custom tag values\nclass CreateEvent(msgspec.Struct, tag=\"create\"):\n    resource: str\n\nclass DeleteEvent(msgspec.Struct, tag=\"delete\"):\n    resource: str\n    soft: bool = True\n\nEvent = CreateEvent | DeleteEvent\n\n# Custom tag field name\nclass V1Request(msgspec.Struct, tag=\"v1\", tag_field=\"version\"):\n    payload: str\n\nclass V2Request(msgspec.Struct, tag=\"v2\", tag_field=\"version\"):\n    payload: str\n    metadata: dict[str, str] = {}\n\nRequest = V1Request | V2Request\n```\n\n<workflow>\n\n## Workflow\n\n### Step 1: Define Structs\n\nCreate msgspec Structs for all data shapes. Use `kw_only=True` for Structs with more than 2 fields. Use `frozen=True` for immutable value objects. Use `forbid_unknown_fields=True` for API-boundary input validation.\n\n### Step 2: Add Constraints\n\nAnnotate fields with `Annotated[Type, Meta(...)]` for numeric ranges, string lengths, and regex patterns. Define reusable constraint aliases at module level to avoid repetition.\n\n### Step 3: Choose Serialization Strategy\n\nUse `msgspec.json` for JSON APIs and `msgspec.msgpack` for binary protocols or internal messaging. Instantiate `Encoder`/`Decoder` once at module level as singletons. Add `enc_hook`/`dec_hook` for custom types (datetime, UUID, Decimal, Enum).\n\n### Step 4: Handle Polymorphism\n\nUse tagged unions (`tag=True` or `tag=\"value\"`) for discriminated unions. Define a union type alias (`Event = CreateEvent | DeleteEvent`) and decode against it. Use `tag_field` to customize the discriminator field name.\n\n### Step 5: Validate\n\nTest round-trip encode/decode. Confirm `ValidationError` is raised for constraint violations. Verify tag dispatch selects the correct Struct type for all union variants.\n\n</workflow>\n\n<guardrails>\n\n## Guardrails\n\n- **Always annotate all fields** -- msgspec requires type annotations; unannotated fields are ignored silently.\n- **Cache Encoder/Decoder as singletons** -- instantiation is expensive; create once at module level and reuse.\n- **Use `kw_only=True` for Structs with >2 fields** -- prevents positional argument confusion and makes instantiation self-documenting.\n- **Use `forbid_unknown_fields=True` at API boundaries** -- rejects payloads with unexpected keys, preventing silent data loss.\n- **Prefer `Meta` constraints over manual validation** -- zero runtime overhead; constraints are checked during decode, not after.\n- **Use `gc=False` for short-lived, non-circular objects** -- eliminates GC overhead for hot-path objects like request/response shapes.\n- **Tagged unions for polymorphism** -- faster than manual dispatch and eliminates `isinstance` chains.\n- **`from __future__ import annotations` rule** — Libraries that define runtime-introspected types (advanced-alchemy models, sqlspec configs, msgspec Structs, dishka providers) avoid `from __future__ import annotations`. Consumer applications MAY and typically SHOULD use it — canonical Litestar apps use it in 100+ files. The restriction applies only to the module that *defines* the Struct, not to handler/service/test modules that *use* it.\n- **Use `strict=False` only at trust boundaries** -- lax coercion is useful for converting legacy dicts but can mask type errors in internal code.\n- **Prefer `sqlspec.utils.serializers.to_json` when sqlspec is in-stack** — its built-in enc_hook covers UUID, datetime, Enum, Decimal, Pydantic, msgspec.Struct, dataclasses, and attrs in one import. Hand-rolling is only needed when sqlspec is not a dependency.\n\n</guardrails>\n\n<validation>\n\n### Validation Checkpoint\n\nBefore delivering msgspec code, verify:\n\n- [ ] All Struct fields have explicit type annotations\n- [ ] If this module defines runtime-introspected types (msgspec.Struct, etc.), no `from __future__ import annotations`. Consumer modules may use it.\n- [ ] Encoder/Decoder instances are module-level singletons (not created per-request)\n- [ ] API-boundary Structs use `forbid_unknown_fields=True`\n- [ ] Numeric/string constraints use `Meta` (not manual `if` checks)\n- [ ] `enc_hook`/`dec_hook` handle all non-native types used in Structs\n- [ ] Tagged union tag values are unique across all variants in a union\n- [ ] `kw_only=True` on Structs with more than 2 fields\n- [ ] If sqlspec is in-stack, to_json is imported from sqlspec.utils.serializers (not hand-rolled)\n\n</validation>\n\n<example>\n\n## Example\n\n**Task:** Define an event system with tagged unions, constraints, and JSON serialization.\n\n```python\nfrom __future__ import annotations  # DO NOT DO THIS in modules that DEFINE msgspec.Struct (library-like) -- consumer handler/service modules MAY use future annotations safely\n```\n\n```python\n# events.py\nfrom typing import Annotated, Literal\nfrom datetime import datetime\nimport uuid\nimport msgspec\nfrom msgspec import Meta\n\n# --- Constraint aliases ---\nNonEmptyStr = Annotated[str, Meta(min_length=1, max_length=255)]\nPositiveInt = Annotated[int, Meta(gt=0)]\n\n# --- Event variants (tagged union) ---\nclass UserCreatedEvent(msgspec.Struct, tag=\"user.created\", tag_field=\"event_type\", kw_only=True, gc=False):\n    event_id: uuid.UUID\n    user_id: PositiveInt\n    email: NonEmptyStr\n    occurred_at: datetime\n\nclass UserDeletedEvent(msgspec.Struct, tag=\"user.deleted\", tag_field=\"event_type\", kw_only=True, gc=False):\n    event_id: uuid.UUID\n    user_id: PositiveInt\n    occurred_at: datetime\n    reason: str | None = None\n\nUserEvent = UserCreatedEvent | UserDeletedEvent\n\n# --- Custom hooks for datetime and UUID ---\ndef enc_hook(obj: object) -> object:\n    if isinstance(obj, datetime):\n        return obj.isoformat()\n    if isinstance(obj, uuid.UUID):\n        return str(obj)\n    raise TypeError(f\"Unsupported type: {type(obj)}\")\n\ndef dec_hook(type: type, obj: object) -> object:\n    if type is datetime:\n        return datetime.fromisoformat(obj)\n    if type is uuid.UUID:\n        return uuid.UUID(obj)\n    raise TypeError(f\"Unsupported type: {type}\")\n\n# --- Singleton codec ---\n_encoder = msgspec.json.Encoder(enc_hook=enc_hook)\n_decoder = msgspec.json.Decoder(UserEvent, dec_hook=dec_hook)\n\ndef encode_event(event: UserEvent) -> bytes:\n    return _encoder.encode(event)\n\ndef decode_event(data: bytes) -> UserEvent:\n    return _decoder.decode(data)\n\n# --- Usage ---\nevent = UserCreatedEvent(\n    event_id=uuid.uuid4(),\n    user_id=42,\n    email=\"alice@example.com\",\n    occurred_at=datetime.utcnow(),\n)\npayload = encode_event(event)\n# b'{\"event_type\":\"user.created\",\"event_id\":\"...\",\"user_id\":42,\"email\":\"alice@example.com\",\"occurred_at\":\"...\"}'\n\nrecovered = decode_event(payload)\nassert isinstance(recovered, UserCreatedEvent)\n```\n\n</example>\n\n---\n\n## References Index\n\nFor detailed guides and reference tables, refer to the following documents in `references/`:\n\n- **[Meta Constraints Reference](references/constraints.md)** -- Full table of all Meta constraint parameters with examples for numeric, string, bytes, and OpenAPI metadata.\n- **[Tagged Union Patterns](references/tagged-unions.md)** -- Discriminated union patterns: default tags, custom tag fields/values, nested unions, API versioning, and event systems.\n- **[Litestar Patterns](references/litestar-patterns.md)** — CamelizedBaseStruct, sqlspec-vs-manual to_json branches, hybrid msgspec + Pydantic schema pattern, `__post_init__` validation for Litestar apps.\n\n---\n\n## Official References\n\n- <https://jcristharif.com/msgspec/>\n- <https://jcristharif.com/msgspec/structs.html>\n- <https://jcristharif.com/msgspec/constraints.html>\n- <https://jcristharif.com/msgspec/json.html>\n- <https://jcristharif.com/msgspec/msgpack.html>\n- <https://jcristharif.com/msgspec/converters.html>\n- <https://jcristharif.com/msgspec/api.html>\n- <https://github.com/jcrist/msgspec>\n\n## Shared Styleguide Baseline\n\n- Use shared styleguides for generic language/framework rules to reduce duplication in this skill.\n- [General Principles](../litestar-styleguide/references/general.md)\n- [Python](../litestar-styleguide/references/python.md)\n- Keep this skill focused on tool-specific workflows, edge cases, and integration details.","tags":["msgspec","litestar","skills","litestar-org","advanced-alchemy","agent-skills","agentskills","ai-agents","claude-code-plugin","claude-code-skills","gemini-cli-extension","htmx"],"capabilities":["skill","source-litestar-org","skill-msgspec","topic-advanced-alchemy","topic-agent-skills","topic-agentskills","topic-ai-agents","topic-claude-code-plugin","topic-claude-code-skills","topic-gemini-cli-extension","topic-htmx","topic-inertia","topic-litestar","topic-mcp","topic-python"],"categories":["litestar-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/litestar-org/litestar-skills/msgspec","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add litestar-org/litestar-skills","source_repo":"https://github.com/litestar-org/litestar-skills","install_from":"skills.sh"}},"qualityScore":"0.453","qualityRationale":"deterministic score 0.45 from registry signals: · indexed on github topic:agent-skills · 7 github stars · SKILL.md body (14,902 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T19:13:55.216Z","embedding":null,"createdAt":"2026-05-18T13:20:59.550Z","updatedAt":"2026-05-18T19:13:55.216Z","lastSeenAt":"2026-05-18T19:13:55.216Z","tsv":"'/jcrist/msgspec':1872 '/litestar-styleguide/references/general.md':1891 '/litestar-styleguide/references/python.md':1893 '/msgspec/':1851 '/msgspec/api.html':1869 '/msgspec/constraints.html':1857 '/msgspec/converters.html':1866 '/msgspec/json.html':1860 '/msgspec/msgpack.html':1863 '/msgspec/structs.html':1854 '0':308,314,346,1579 '0.0':359,371,839 '0.001':337 '000':317 '1':299,353,394,758,804,984,1570 '10':316 '100':126,302,1308 '100.0':361 '2':149,205,327,760,1003,1024,1188,1487 '255':1573 '3':1052 '4':329,1091 '42':707,744,1740,1758 '5':1127 '5432':217 '5x':54 '604':74 'a-z':324 'across':1473 'activ':4,854 'add':1025,1078 'advanc':1280 'advanced-alchemi':1279 'alchemi':1281 'alia':1109 'alias':340,1044,1563 'alic':396,709,759,806 'alice@example.com':1742,1760 'alreadi':557 'alway':132,1154 'anim':906,917,927 'annot':85,103,124,133,139,283,294,304,310,319,332,342,348,355,835,1027,1030,1155,1161,1270,1293,1404,1419,1522,1541,1548,1565,1575 'api':264,398,1019,1060,1206,1438,1820 'api-boundari':1018,1437 'apirespons':244 'app':121,513,1304,1846 'appli':1312 'applic':1295 'argument':1192 'array':222,232 'array-lik':221 'assert':1767 'attr':569,1375 'auto':3 'auto-activ':2 'avoid':1049,1289 'await':600 'b':392,407,609,919,1750 'backend.publish':601 'baselin':1875 'basic':158 'binari':411,1064 'bob':761 'bool':219,855,905,946 'boundari':265,1020,1207,1334,1439 'branch':538,543,608,1835 'break':130 'breed':895,924 'broadcast':530 'built':1362 'built-in':1361 'byte':389,520,598,688,692,1719,1727,1802 'cach':379,1167 'camel':247 'camelizedbasestruct':1828 'canon':119,505,1302 'case':1904 'cat':898,908 'chain':1266 'channel':529,603 'check':1228,1453 'checkpoint':1392 'choos':1053 'circular':1242 'class':61,160,173,207,229,243,266,290,362,795,886,888,897,916,931,938,955,965,1584,1609 'code':69,1350,1396 'codec':26,1700 'coerc':732,742 'coercion':699,1336 'compact':228,413 'compat':733 'config':208,1284 'confirm':1134 'confus':1193 'constraint':28,278,339,1026,1043,1139,1219,1226,1447,1514,1562,1787,1795 'consum':104,127,1294,1420,1535 'context':532 'conveni':399 'convert':19,701,771,786,1340 'correct':915,1146 'cover':562,1366 'creat':254,935,987,1174,1433 'createdat':259 'createev':932,949,1111 'creation':820 'custom':422,776,928,951,1084,1121,1639,1815 'd':328 'data':34,386,402,414,419,757,764,992,1215,1726,1731 'dataclass':68,568,791,793,794,1373 'dataclass/dict/object':787 'datetim':429,433,435,447,475,525,564,628,1086,1368,1551,1553,1608,1631,1642,1654,1682 'datetime.fromisoformat':477,1684 'datetime.utcnow':1745 'dec':16,465,501,503,773,782,784,1081,1456,1672,1710,1712 'decim':431,527,566,1088,1370 'decod':383,498,1071,1114,1230,1707,1724,1764 'decoder.decode':391,1730 'def':438,464,643,683,1645,1671,1714,1723 'default':644,682,716,848,851,859,865,877,1813 'defin':22,89,985,1041,1105,1274,1318,1408,1507,1530 'definit':154,828 'delet':942 'deleteev':939,950,1112 'deliv':1394 'depend':1390 'deseri':49,909 'detail':1774,1907 'dict':197,747,756,765,976,1342 'direct':813 'discount':369 'discrimin':29,868,1103,1123,1810 'dishka':1287 'dispatch':1143,1262 'document':1199,1783 'dog':889,907,921 'dt':630,665 'dt.date':672 'dt.datetime':658 'dt.utc':661 'dto':33 'duplic':1885 'dynam':818 'dynamicmodel':840,842 'edg':1903 'effici':58 'elimin':1244,1264 'email':167,1604,1741,1759 'enc':14,439,494,496,560,623,680,1079,1364,1454,1646,1703,1705 'encod':224,226,381,492,620,678,1070,1701,1715,1747 'encode/decode':1133 'encoder.encode':387,696,1721 'encoder/decoder':378,1168,1425 'enum':526,565,1089,1369 'error':1347 'etc':1414 'event':174,193,607,948,1110,1509,1580,1591,1598,1616,1623,1716,1717,1722,1725,1733,1735,1748,1749,1751,1754,1765,1823 'events.py':1544 'exampl':1505,1798 'expens':1173 'explicit':1402 'export':552 'f':459,488,604,1666,1695 'fals':179,185,220,740,1235,1330,1597,1622 'faster':64,1259 'field':135,150,206,240,262,271,827,829,843,849,863,879,912,953,961,971,1004,1015,1028,1119,1124,1157,1163,1189,1203,1400,1444,1488,1590,1615 'fields/values':1817 'file':128,1309 'flexmodel':860,862 'float':236,238,305,333,356,836 'focus':1897 'follow':1782 'forbid':269,1013,1201,1442 'frozen':176,180,1006 'full':1790 'function':397 'futur':83,101,123,1268,1291,1417,1520,1540 'gc':178,184,187,1234,1245,1596,1621 'ge':313,358,838 'general':1889 'generic':1880 'github.com':1871 'github.com/jcrist/msgspec':1870 'gt':307,345,1578 'guardrail':1153 'guid':1775 'h':666 'hand':617,1380,1503 'hand-rol':616,1379,1502 'handl':523,1092,1458 'handler':110 'handler/service':1536 'handler/service/test':1323 'hashabl':183 'high':43 'high-perform':42 'hook':15,17,423,440,466,495,497,502,504,561,624,681,774,783,785,1080,1082,1365,1455,1457,1640,1647,1673,1704,1706,1711,1713 'host':213 'hot':1249 'hot-path':1248 'hybrid':1836 'id':163,249,365,393,706,710,726,741,797,803,830,852,1599,1602,1624,1627,1736,1739,1755,1757 'ignor':1165 'immut':182,1009 'import':7,84,102,156,282,284,288,374,434,436,576,590,627,631,635,639,641,703,792,822,871,875,1269,1292,1378,1418,1498,1521,1547,1552,1554,1556,1560 'in-stack':547,613,1357,1492 'index':1772 'indoor':904 'init':1842 'input':1021 'inspect':910 'instal':558 'instanc':1426 'instanti':1069,1171,1196 'int':164,216,250,276,311,343,729,766,798,831,853,1576 'integr':1906 'intern':1067,1349 'introspect':96,1277,1411 'isinst':445,451,649,656,670,690,1265,1652,1658,1768 'jcristharif.com':1850,1853,1856,1859,1862,1865,1868 'jcristharif.com/msgspec/':1849 'jcristharif.com/msgspec/api.html':1867 'jcristharif.com/msgspec/constraints.html':1855 'jcristharif.com/msgspec/converters.html':1864 'jcristharif.com/msgspec/json.html':1858 'jcristharif.com/msgspec/msgpack.html':1861 'jcristharif.com/msgspec/structs.html':1852 'json':376,517,578,580,583,585,592,595,632,685,754,1059,1353,1496,1516,1834 'json-load':753 'jsonb':534 'keep':1894 'key':746,748,769,1212 'keyword':201 'keyword-on':200 'kg':331 'kw':141,210,844,995,1182,1479,1593,1618 'lab':925 'label':367 'language/framework':1881 'lax':730,1335 'le':315,360 'legaci':801,810,816,1341 'legacyus':796,802 'length':298,301,352,1037,1569,1572 'level':1047,1075,1178,1430 'librari':46,93,1272,1533 'library-lik':92,1532 'like':94,223,233,1252,1534 'liter':876,1549 'litestar':32,120,506,512,1303,1825,1845 'live':191,1239 'load':755 'log':531 'loss':1216 'm':664,667 'make':1195 'manual':1221,1261,1451,1832 'mask':1345 'match':509,540 'match-your-stack':508 'max':300,1571 'may':113,1296,1422,1538 'memori':57 'memory-effici':56 'messag':1068 'messagepack':410 'meta':289,296,306,312,321,334,344,350,357,837,1032,1218,1449,1561,1567,1577,1786,1794 'metadata':975,1805 'min':297,351,1568 'mismatch':720 'mode':715,731 'model':24,1282 'modul':87,105,1046,1074,1177,1316,1324,1407,1421,1429,1528,1537 'module-level':1428 'msgspec':1,6,23,37,39,131,136,157,285,287,375,642,704,823,872,988,1158,1285,1395,1557,1559,1837 'msgspec.convert':722,736,763,779,808,815 'msgspec.defstruct':841,861 'msgspec.json':10,1057 'msgspec.json.decode':406,918 'msgspec.json.decoder':384,499,1708 'msgspec.json.encode':403 'msgspec.json.encoder':382,493,679,1702 'msgspec.meta':9 'msgspec.msgpack':11,1062 'msgspec.msgpack.decode':418 'msgspec.msgpack.encode':415 'msgspec.struct':8,90,162,175,209,231,245,268,292,364,571,890,899,933,940,957,967,1372,1413,1531,1586,1611 'msgspec.structs.asdict':809 'multipl':335 'must':97,727 'myapp.utils.serialization':589 'myapp/utils/serialization.py':573,626 'mystruct':500 'name':165,273,293,395,708,799,805,832,857,887,893,902,922,954,1125 'nativ':427,1462 'need':515,1384 'nest':1818 'non':426,1241,1461 'non-circular':1240 'non-nat':425,1460 'none':78,169,170,1634,1635 'nonemptystr':347,368,1564,1605 'numer':1034,1800 'numeric/string':1446 'obj':441,446,452,456,463,469,478,485,1648,1653,1659,1663,1670,1676,1685,1692 'obj.isoformat':449,1656 'object':192,199,442,443,470,471,1011,1243,1251,1649,1650,1677,1678 'occur':1606,1629,1743,1761 'offici':1847 'one':1377 'openapi':1804 'option':80,172 'order':363,596,605 'order.id':606 'overhead':1225,1246 'paramet':1796 'path':1250 'pattern':322,1040,1808,1812,1826,1840 'payload':196,593,602,963,973,1209,1746,1766 'pep':73 'per':1435 'per-request':1434 'percentag':354,370 'perform':44,171 'pick':536,914 'point':230 'polymorph':1093,1258 'port':215 'posit':1191 'positiveint':341,366,1574,1603,1628 'post':1841 'prefer':1217,1351 'prevent':1190,1213 'price':303 'principl':1890 'product':291 'project':542 'protocol':1065 'provid':1288 'pydant':66,567,1371,1838 'python':45,155,279,373,572,587,625,702,821,870,1518,1543,1892 'quantiti':309 'quick':151 'r':323 'rais':457,486,717,1137,1664,1693 'rang':1035 'raw':705,723,737,780 're':551 're-export':550 'reason':1632 'recommend':203 'recov':1763,1769 'reduc':1884 'refer':152,1771,1777,1779,1785,1788,1848 'references/constraints.md':1789 'references/litestar-patterns.md':1827 'references/tagged-unions.md':1809 'regex':1039 'regular':60 'reject':260,1208 'renam':239,246 'repetit':1050 'request':979,1436 'request/response':1253 'requir':137,1159 'resourc':936,943 'restrict':1311 'result':762 'return':448,454,476,483,652,659,673,675,693,695,1655,1661,1683,1690,1720,1729 'reus':1180 'reusabl':338,1042 'rex':923 'roll':618,1381,1504 'round':1131 'round-trip':1130 'rule':71,86,1271,1882 'runtim':95,824,1224,1276,1410 'runtime-introspect':1275,1409 'safe':1542 'schema':1839 'score':834 'select':1144 'self':1198 'self-docu':1197 'serial':25,48,63,242,251,257,372,507,555,1054,1517 'servic':111 'shape':35,993,1254 'share':1873,1877 'short':190,1238 'short-liv':189,1237 'silent':1166,1214 'singleton':377,1077,1170,1431,1699 'skill':38,1888,1896 'skill-msgspec' 'skip':186 'sku':318 'slight':400 'slower':401 'soft':945 'source-litestar-org' 'specif':1901 'sqlspec':545,553,610,1283,1355,1386,1490,1830 'sqlspec-vs-manu':1829 'sqlspec.utils.serializers':575,1500 'sqlspec.utils.serializers.to':1352 'ssl':218 'stack':511,549,615,1359,1494 'step':983,1023,1051,1090,1126 'str':166,168,195,198,214,256,274,295,320,349,455,647,653,676,745,767,768,800,833,894,896,903,937,944,964,974,977,978,1566,1633,1662 'strategi':1055 'strftime':662 'strict':714,739,1329 'strictinput':267 'string':713,750,1036,1801 'struct':52,109,145,153,159,789,819,825,986,989,999,1147,1186,1286,1320,1399,1440,1466,1483 'style':70 'styleguid':1874,1878 'subclass':91 'system':1510,1824 'sz':668 'tabl':1778,1791 'tag':12,866,878,882,891,900,929,934,941,952,958,960,968,970,1095,1097,1100,1118,1142,1255,1467,1469,1512,1582,1587,1589,1612,1614,1806,1814,1816 'task':1506 'test':112,1129 'tool':1900 'tool-specif':1899 'topic-advanced-alchemy' 'topic-agent-skills' 'topic-agentskills' 'topic-ai-agents' 'topic-claude-code-plugin' 'topic-claude-code-skills' 'topic-gemini-cli-extension' 'topic-htmx' 'topic-inertia' 'topic-litestar' 'topic-mcp' 'topic-python' 'trip':1132 'true':143,177,181,212,234,272,521,599,770,846,856,892,901,947,997,1007,1016,1098,1184,1204,1445,1481,1595,1620 'trust':1333 'tupl':225 'type':138,194,281,408,420,428,461,462,467,468,473,480,490,491,634,698,719,734,777,858,874,881,911,920,926,1031,1085,1108,1148,1160,1278,1346,1403,1412,1463,1546,1592,1617,1668,1669,1674,1675,1680,1687,1697,1698,1752 'typeerror':458,487,1665,1694 'typic':115,514,1298 'unannot':1162 'unexpect':1211 'union':13,30,76,867,869,1096,1104,1107,1151,1256,1468,1478,1513,1583,1807,1811,1819 'uniqu':1472 'unknown':261,270,1014,1202,1443 'unsupport':460,489,1667,1696 'usag':586,1732 'use':20,72,99,108,117,122,140,751,994,1005,1012,1056,1094,1117,1181,1200,1233,1300,1305,1326,1328,1338,1423,1441,1448,1464,1539,1876 'user':161,248,385,388,390,404,405,409,416,417,421,721,724,735,738,778,807,811,814,817,1601,1626,1738,1756 'user.created':1588,1753 'user.deleted':1613 'usercreatedev':1585,1637,1734,1770 'userdeletedev':1610,1638 'userev':1636,1709,1718,1728 'userid':253 'userwithuuid':781 'uuid':430,437,524,563,638,640,651,1087,1367,1555,1644 'uuid.uuid':453,482,484,1600,1625,1660,1689,1691 'uuid.uuid4':1737 'v1':959 'v1request':956,980 'v2':969 'v2request':966,981 'valid':27,51,277,1022,1128,1222,1391,1843 'validationerror':725,1135 'valu':275,518,645,650,654,657,671,677,686,691,694,697,883,930,1010,1101,1470 'value.astimezone':660 'value.isoformat':674 'variant':1152,1475,1581 'verifi':1141,1397 'version':962,972,1821 'violat':1140 'vs':1831 'weight':330 'without':129 'workflow':982,1902 'write':535 'x':235 'y':237,663 'z':326 'zero':1223","prices":[{"id":"e3b87a3d-9b46-40a9-b7bc-28a9eeb9237d","listingId":"115117f0-e843-420b-80ae-f2087146609a","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"litestar-org","category":"litestar-skills","install_from":"skills.sh"},"createdAt":"2026-05-18T13:20:59.550Z"}],"sources":[{"listingId":"115117f0-e843-420b-80ae-f2087146609a","source":"github","sourceId":"litestar-org/litestar-skills/msgspec","sourceUrl":"https://github.com/litestar-org/litestar-skills/tree/main/skills/msgspec","isPrimary":false,"firstSeenAt":"2026-05-18T13:20:59.550Z","lastSeenAt":"2026-05-18T19:13:55.216Z"}],"details":{"listingId":"115117f0-e843-420b-80ae-f2087146609a","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"litestar-org","slug":"msgspec","github":{"repo":"litestar-org/litestar-skills","stars":7,"topics":["advanced-alchemy","agent-skills","agentskills","ai-agents","claude-code-plugin","claude-code-skills","gemini-cli-extension","htmx","inertia","litestar","mcp","python","sqlspec"],"license":"mit","html_url":"https://github.com/litestar-org/litestar-skills","pushed_at":"2026-05-13T16:04:09Z","description":"Opinionated first-party agent skills, plugins, subagents, slash commands, and MCP servers for the Litestar framework ecosystem — publishable to Claude Code, Gemini CLI, Codex CLI, Cursor, OpenCode, and VS Code/Copilot from a single repo.","skill_md_sha":"65a20f46ac7d66a29a80747ef74eeb3bdf51081c","skill_md_path":"skills/msgspec/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/litestar-org/litestar-skills/tree/main/skills/msgspec"},"layout":"multi","source":"github","category":"litestar-skills","frontmatter":{"name":"msgspec","description":"Auto-activate for msgspec imports, msgspec.Struct, msgspec.Meta, msgspec.json, msgspec.msgpack, tagged unions, enc_hook, dec_hook, or convert(). Use when defining msgspec models, serialization codecs, validation constraints, discriminated unions, or Litestar DTO data shapes. Not for Pydantic, dataclasses, attrs, or ORM models unless converting at a boundary."},"skills_sh_url":"https://skills.sh/litestar-org/litestar-skills/msgspec"},"updatedAt":"2026-05-18T19:13:55.216Z"}}