[API reference](https://evolu.dev/docs/api-reference) › [@evolu/common](https://evolu.dev/docs/api-reference/common) › [local‑first/Protocol](https://evolu.dev/docs/api-reference/common/local-first/Protocol) › createProtocolMessageFromCrdtMessages

```ts
function createProtocolMessageFromCrdtMessages(
  deps: RandomBytesDep,
): (
  owner: Owner,
  messages: readonly [CrdtMessage, CrdtMessage],
  maxSize?: number &
    Brand<"NonNaN"> &
    Brand<"Finite"> &
    Brand<"Int"> &
    Brand<"Between1000000-100000000">,
) => ProtocolMessage;
```

Defined in: [packages/common/src/local-first/Protocol.ts:595](https://github.com/evoluhq/evolu/blob/113517df8a8da4e4eed41363077878e657b22fca/packages/common/src/local-first/Protocol.ts#L595)

Creates a [ProtocolMessage](https://evolu.dev/docs/api-reference/common/local-first/Protocol/type-aliases/ProtocolMessage) from CRDT messages.

The message holds the leading CRDT messages that fit `maxSize`, by default
[defaultProtocolMessageMaxSize](https://evolu.dev/docs/api-reference/common/local-first/Protocol/variables/defaultProtocolMessageMaxSize), measured exactly. When one does not
fit, it and the rest are left out, and the message ends with a range that
makes the non-initiator answer with ranges. Sync then sends them in later
rounds, even over unidirectional and stateless transports, because every
change within [maxMutationSize](https://evolu.dev/docs/api-reference/common/local-first/Evolu/variables/maxMutationSize) fits an empty message.