Ditzy is a transport-agnostic universal multi-message encoding scheme, allowing stateful bidirectional communications regardless of the statefulness of the underlying transport. With the state of the reconstructed tunnel fully decoupled from the underlying transport, possibilities are endless. How Ditzy performs is entirely dependent on implementation.

This project is inspired by Tor HTTP Meek, MIDI 1.0 and QUIC.

💌 Feel your messages delivered safely by your trustworthy Ponyvillan mailmare!

The first draft was written on 18th Nov 2021, with the next iteration on 5th Feb 2023. The current draft is written on 29th June 2023.


  • State of tunneled connections are decoupled from their underlying transports
  • Seamless connection migration on connection losses and IP changes
  • Total control over frame transmission

Use cases

  • Bidirectional communication through incapable infrastructure (e.g. CDNs, request reflectors)
  • Stablizing communication over unstable networks
  • Replacing QUIC where UDP communication is not feasible
  • Connection multiplexing
  • Connection splitting


Reference implementation API docs



The underlying transport interface to be used by DitzyStream. Connection management and congestion control happens here.

This interface needs to implement the following public methods to let DitzyStream function properly.

DitzyDriver {
	send(): WritableStream, // Where data gets sent out
	onmessage: ReadableStream, // Where data gets received


The master stream, where underlying sockets gets multiplexed and de-multiplexed. Individual sockets can be established with DitzySocket or DitzyPipe.

DitzyStream {
	driver: DitzyDriver, // The underlying driver
	pipe(): DitzyPipe, // Creates a new connection
	sock(): DitzySocket, // Creates a new connection


The raw interface sending data to and receiving data from as streams.

DitzyPipe {
	i: ReadableStream,
	o: WritableStream,


A WebSocket-like interface to send messages to and receive messages from.

DitzySocket {
	readyState: Number <readonly>,
	textOnly: Boolean,
	send(msg: Uint8Array|String),
	close(): null,
	onclose: Uint8Array|String,
	onmessage: Uint8Array|String,
	onopen: null