> ## Documentation Index
> Fetch the complete documentation index at: https://docs.rebind.gg/llms.txt
> Use this file to discover all available pages before exploring further.

# rb.pipe

> Exchange messages with another process on the same PC through shared memory.

`rb.pipe` opens a region of shared memory that the script and another process
both map, and passes messages through it in both directions. A script reaches
for it to talk to a companion program on the same PC.

**Needs:** the `exec` [permission](https://docs.rebind.gg/reference/sdk/modeline.md#permissions); Windows.

This script opens a pipe, sends one message, then checks for replies ten times a
second for five seconds:

```luau theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
-- rebind: min_sdk=3.9.0 name=example version=1.0.0 permissions=exec platforms=windows
local pipe = rb.pipe.open("overlay-bridge", { size = 4096 })
rb.log.info(pipe.name, pipe.size, pipe.capacity)  -- overlay-bridge	4096	2036
pipe:write("hello")

rb.run(function()
  for _ = 1, 50 do
    local reply = pipe:read()
    if reply then
      rb.log.info("reply", reply)
    end
    rb.sleep(100)
  end
  pipe:close()
end)
```

`rb.pipe.open(name: string, options: { size: number? }?) -> PipeHandle`

`open` checks the `exec` permission first on every platform, then raises
`Pipe is only supported on Windows` on any platform but Windows.

The region is the Windows object `Local\Rebind_<name>`. `name` is 1 to 64 ASCII
letters, digits, `-` or `_`. `size` (default 65,536) is rounded up to a power of
two and clamped to 1,024 to 16 MiB. Opening a name the script already has open
raises `Pipe '<name>' is already open`.

| Member | Meaning |
| - | - |
| `pipe.name` | the name |
| `pipe.size` | total bytes |
| `pipe.capacity` | largest message: `size / 2 - 12` |
| `pipe:read() -> string?` | the latest message from the other process, or `nil` when nothing new arrived |
| `pipe:write(data: string) -> ()` | writes a message; raises when it exceeds `capacity` |
| `pipe:close() -> ()` | releases the region |

After `close`, `read` and `write` raise `Pipe '<name>' is closed`.

## Wire protocol

The region holds two channels. The script writes channel A at offset `0` and
reads channel B at offset `size / 2`; the other process does the reverse. Each
channel is a 12-byte header and the payload:

| Bytes | Field |
| - | - |
| `0..8` | `u64` sequence number, little-endian, increased on every write |
| `8..12` | `u32` payload length, little-endian |
| `12..` | payload, up to `capacity` bytes |

A writer stores the payload, then the length, then the sequence number. A reader
reads only when the sequence number changed since its last read. Each channel
holds one message: an unread message is overwritten by the next write.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.