Two unrelated ways to pack data, both thin wrappers rather than reimplementations: `ByteWriter`/`ByteReader` for bytes, `Json` for text.

```csharp
using Udonite.Serialization;

byte[] payload = new ByteWriter().WriteInt32(7).WriteString("hi").ToArray();

string json = Json.Serialize(dictionaryOrIJsonSerializable);
```

**Bytes, because Udon has no serializer of its own.** `ByteWriter`/`ByteReader` cover exactly the
primitives Udon's network layer can natively marshal — the 32-bit-and-under scalars, `string`,
`byte[]`, `Vector2`, `Vector3`, `Quaternion` — a deliberate core rather than a full mirror of
`System.BitConverter`, since every method a reached class declares costs heap for the life of the
program.

**JSON, because Udon already has one.** `Json` wraps `VRCJson` — Udon's own parser — rather than
building a second one. It hides `DataToken`, VRChat's own plumbing type, from most callers: a
type opts in by implementing `IJsonSerializable`, and `Json.Serialize<T>`/`Deserialize<T>` do the
rest.

## What is in it

| Type | For |
|---|---|
| `ByteWriter`, `ByteReader` | Packing to `byte[]` — a message payload, a save format, anything you own the shape of |
| `Json`, `IJsonSerializable` | Packing to JSON text, for anything that has to be JSON — an external API, a human-editable file |

## Where to go next

[Getting started](/docs/serialization/getting-started) packs a value to bytes and a type to JSON.

[Reference](/docs/serialization/reference) is every member of both halves.
