# Serde Reference

`@derive(Serialize)` and `@derive(Deserialize)` generate JSON serialization with cycle detection,
forward references, and runtime validation. This section is the complete reference; the
[Serialize](/docs/builtin-macros/serialize) and [Deserialize](/docs/builtin-macros/deserialize)
pages cover the basics.

## Generated API

For a **class**, the macros emit static methods plus standalone functions that the statics delegate
to:

```typescript
/** @derive(Serialize, Deserialize) */
class User {
    name: string;
    email: string;
}

// Serialize
User.serialize(user); // string
User.serialize(user, true); // keep __type/__id metadata
User.serializeWithContext(user, ctx); // Record<string, unknown>

// Deserialize
const r = User.deserialize(input);
if (r.success) {
    r.value; // User
} else {
    r.errors; // Array<{ field: string; message: string }>
}

User.deserialize(input, { freeze: true }); // freeze all deserialized objects
User.hasShape(obj); // boolean — required keys present
User.is(value); // type guard
User.validateField('email', value);
User.validateFields({ email: '…' });
```

### Static wrappers vs standalone functions

This distinction trips people up, so it's worth stating plainly:

| Declaration    | What you get                                       |
| -------------- | -------------------------------------------------- |
| **Class**      | `static X(...)` **and** standalone `{camel}X(...)` |
| **Interface**  | standalone `{camel}X(...)` only                    |
| **Type alias** | standalone `{camel}X(...)` only                    |
| **Enum**       | standalone `{camel}X(...)` only                    |

There is no class to attach statics to for the last three, so they get functions like
`userSerialize(value)` and `userDeserialize(input)`. With `generateConvenienceConst` enabled (the
default), a grouping `const` — or, for enums, a merged `namespace` — is also emitted so you can
still write `User.serialize(...)`.

### Enums differ

Enum `deserialize` **throws** on invalid input rather than returning the success/errors union. Enum
`serialize` takes no `keepMetadata` parameter.

## Metadata and `keepMetadata`

`serialize` adds `__type` and `__id` fields internally to support cycle detection, then **strips
them** from the JSON output unless you pass `keepMetadata: true`. If you're round-tripping a cyclic
graph, keep the metadata; if you're producing an API payload, leave it off.

## Section contents

- **[Validators](/docs/serde/validators)** — all 50 validator names and the three ways to apply them
- **[Container Options](/docs/serde/container-options)** — `renameAll`, tagging modes,
  `denyUnknownFields`
- **[Field Options](/docs/serde/field-options)** — skip, rename, default, flatten, custom functions,
  `format`
- **[Foreign Types](/docs/serde/foreign-types)** — serializing types you don't own
- **[Cycles & References](/docs/serde/cycles-and-references)** — cycle detection, forward refs,
  `freeze`
