Remote Editor Protocol v1
Last updated: April 11, 2026
Communication protocol between the Arshes app and the Remote Editor server.
Terminology
| Term | Description |
|---|---|
| Arshes app | iOS client. Compiles and renders shaders. |
| Server | Remote Editor server. Sends shader compilation requests to the Arshes app and receives results. |
Transport
The Arshes app connects to the server via WebSocket (RFC 6455). Both ws:// (unencrypted) and wss:// (TLS) schemes are supported.
Connection
Endpoint
The Arshes app connects to the following endpoint:
ws(s)://{host}:{port}/
| Parameter | Description |
|---|---|
host |
Server hostname or IP address |
port |
Port number (default: 10080) |
Disconnection
Either side may send a WebSocket close frame to disconnect. The Arshes app may disconnect at any time (e.g. when the user navigates away or the app enters background on iOS).
Reconnection
After disconnection, the Arshes app may reconnect at any time (e.g. when returning to foreground). Each new connection is treated as a fresh session — the app performs the full handshake again.
Message Format
All messages are sent and received as JSON over WebSocket text frames.
{
"type": "<message type>",
"payload": { ... }
}
Messages
hello (Arshes app → Server)
Initiates authentication and protocol version agreement. Must be the first message sent after connection.
{
"type": "hello",
"payload": {
"protocolVersion": 1,
"token": "<auth token>"
}
}
| Field | Type | Description |
|---|---|---|
protocolVersion |
int | Protocol version |
token |
string | Authentication token. How the token is obtained is outside the scope of this protocol (depends on deployment). |
helloResult (Server → Arshes app)
Returns the handshake result.
Success:
{
"type": "helloResult",
"payload": {
"code": "ok",
"protocolVersion": 1
}
}
Failure:
{
"type": "helloResult",
"payload": {
"code": "unauthorized",
"message": "Invalid authentication token"
}
}
| Field | Type | Required | Description |
|---|---|---|---|
code |
string | Yes | Result code |
protocolVersion |
int | No | Protocol version adopted by the server. Present only on success. |
message |
string | No | Human-readable error description. Present only on failure. |
Result codes:
| Code | Description |
|---|---|
ok |
Handshake succeeded |
unauthorized |
Authentication token is invalid or missing |
unsupported_version |
The requested protocol version is not supported by the server |
- On failure, the server closes the connection after sending
helloResult. - No re-authentication occurs on an established connection.
- On reconnection, the Arshes app sends
helloagain.
compileShader (Server → Arshes app)
Requests shader compilation.
{
"type": "compileShader",
"payload": {
"code": "<Slang shader code>",
"image": true
}
}
| Field | Type | Required | Description |
|---|---|---|---|
code |
string | Yes | Slang shader source code |
image |
bool | No | If true, the Arshes app includes a rendered image in compileResult. Defaults to false. |
Upon receiving this message, the Arshes app compiles the shader and returns the result via compileResult.
compileResult (Arshes app → Server)
Returns the shader compilation result.
{
"type": "compileResult",
"payload": {
"success": true,
"errorMessage": null,
"image": "<base64-encoded JPEG image>"
}
}
| Field | Type | Required | Description |
|---|---|---|---|
success |
bool | Yes | true if compilation succeeded |
errorMessage |
string | No | Compilation error message. Present only on failure. |
image |
string | No | Base64-encoded JPEG of the rendered result. Present only on success and when requested by compileShader.image. |
sendShader (Arshes app → Server)
Sends the current shader code from the Arshes app to the server.
{
"type": "sendShader",
"payload": {
"code": "<Slang shader code>"
}
}
| Field | Type | Description |
|---|---|---|
code |
string | The Slang shader code currently being edited |
syncShaderSpec (Arshes app → Server)
Sends shader API specification to the server. Must be sent after a successful handshake (helloResult with code: "ok").
{
"type": "syncShaderSpec",
"payload": {
"entryPoints": [
{ "name": "...", "description": "...", "code": "..." }
],
"uniforms": [
{ "name": "...", "description": "...", "code": "..." }
],
"attributes": [
{ "description": "...", "code": "...", "format": "..." }
]
}
}
| Field | Type | Description |
|---|---|---|
entryPoints |
EntryPoint[] | Shader entry points (fragment, vertex, compute) |
uniforms |
Uniform[] | Available uniform variables |
attributes |
Attribute[] | Available shader attributes |
EntryPoint: { name: string, description: string, code: string }
Uniform: { name: string, description: string, code: string }
Attribute: { description: string, code: string, format: string }
Sequences
Handshake and Initial Sync
Arshes app Server
| |
|--- WebSocket connect ------->|
|<-- connection established ---|
| |
|--- hello ------------------->|
|<-- helloResult --------------|
| |
|--- syncShaderSpec ---------->| (required)
| |
Shader Compilation
Server Arshes app
| |
|--- compileShader ----------->|
| |-- compile
| |
|<-- compileResult ------------|
| |
Sending Shader from Arshes App
Arshes app Server
| |
|--- sendShader -------------->| (user action)
| |