# symfony/ux-turbo architecture

> Architecture diagram of the GitHub repository symfony/ux-turbo, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-29). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/symfony/ux-turbo
- Repository: https://github.com/symfony/ux-turbo

## Overview

Symfony UX Turbo connects Symfony-rendered pages and stream responses to Hotwire Turbo in the browser, and can broadcast entity changes to connected users. The main request path is a Symfony controller returning a page, frame, or Turbo Stream response that the browser applies; the live-update path collects Doctrine changes, renders broadcast actions, and dispatches updates through configured transports such as Mercure. Twig helpers and transport renderers support these flows. The tree and sampled source establish the main wiring; some behavior is documented but its implementation was not sampled.

Main entry points: [`assets/src`](https://github.com/symfony/ux-turbo/tree/3.x/assets/src) (Turbo browser), [`src/TurboStreamResponse.php`](https://github.com/symfony/ux-turbo/blob/3.x/src/TurboStreamResponse.php) (Stream response), [`src/Doctrine/BroadcastListener.php`](https://github.com/symfony/ux-turbo/blob/3.x/src/Doctrine/BroadcastListener.php) (Doctrine lifecycle), [`src/Twig/TurboRuntime.php`](https://github.com/symfony/ux-turbo/blob/3.x/src/Twig/TurboRuntime.php) (Twig runtime)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_http["Symfony responses"]
  node_frame["Frame handling<br/>[TurboFrame.php]"]
  node_request["Request listener"]
  node_stream_response["Stream response"]
  node_stream_helper["Stream markup<br/>[TurboStream.php]"]
  node_twig["Twig helpers"]
  node_templates["Turbo templates"]
end

subgraph group_client["Browser Turbo"]
  node_browser["Turbo browser"]
  node_mercure_source["Mercure stream source"]
end

subgraph group_broadcast["Entity broadcasts"]
  node_doctrine["Doctrine lifecycle"]
  node_broadcast_attribute["Broadcast settings<br/>[Broadcast.php]"]
  node_broadcaster_interface["Broadcaster interface"]
  node_imux["Broadcaster dispatch"]
  node_twig_broadcaster["Twig action renderer"]
  node_mercure_broadcaster["Mercure broadcaster<br/>[Broadcaster.php]"]
end

subgraph group_integration["Bundle integration"]
  node_stream_listen["Mercure listen renderer"]
  node_runtime["Twig runtime<br/>[TurboRuntime.php]"]
  node_extension["Bundle configuration<br/>[TurboExtension.php]"]
end

node_user(("User"))
node_controller["Symfony controller"]
node_hub["Mercure hub"]

node_user -->|"requests page"| node_controller
node_controller -->|"checks frame"| node_frame
node_controller -->|"returns stream"| node_stream_response
node_stream_response -->|"builds markup"| node_stream_helper
node_controller -->|"renders page"| node_twig
node_twig -->|"renders components"| node_templates
node_request -->|"sets request format"| node_controller
node_stream_response -->|"returns stream HTML"| node_browser
node_templates -->|"serves HTML"| node_browser
node_browser -->|"updates interface"| node_user
node_doctrine -->|"reads settings"| node_broadcast_attribute
node_doctrine -->|"broadcasts changes"| node_broadcaster_interface
node_imux -->|"implements dispatch"| node_broadcaster_interface
node_twig_broadcaster -->|"decorates dispatch"| node_imux
node_twig_broadcaster -.->|"renders actions"| node_mercure_broadcaster
node_mercure_broadcaster -->|"publishes update"| node_hub
node_runtime -->|"renders listener"| node_stream_listen
node_runtime -->|"renders source"| node_mercure_source
node_stream_listen -->|"provides listen markup"| node_browser
node_mercure_source -->|"provides source markup"| node_browser
node_extension -->|"configures services"| node_runtime
node_extension -->|"registers listener"| node_doctrine

click node_frame "https://github.com/symfony/ux-turbo/blob/3.x/src/TurboFrame.php"
click node_request "https://github.com/symfony/ux-turbo/blob/3.x/src/Request/RequestListener.php"
click node_stream_response "https://github.com/symfony/ux-turbo/blob/3.x/src/TurboStreamResponse.php"
click node_stream_helper "https://github.com/symfony/ux-turbo/blob/3.x/src/Helper/TurboStream.php"
click node_twig "https://github.com/symfony/ux-turbo/tree/3.x/src/Twig"
click node_templates "https://github.com/symfony/ux-turbo/tree/3.x/templates/components"
click node_browser "https://github.com/symfony/ux-turbo/tree/3.x/assets/src"
click node_mercure_source "https://github.com/symfony/ux-turbo/blob/3.x/src/Bridge/Mercure/MercureStreamSourceRenderer.php"
click node_doctrine "https://github.com/symfony/ux-turbo/blob/3.x/src/Doctrine/BroadcastListener.php"
click node_broadcast_attribute "https://github.com/symfony/ux-turbo/blob/3.x/src/Attribute/Broadcast.php"
click node_broadcaster_interface "https://github.com/symfony/ux-turbo/blob/3.x/src/Broadcaster/BroadcasterInterface.php"
click node_imux "https://github.com/symfony/ux-turbo/blob/3.x/src/Broadcaster/ImuxBroadcaster.php"
click node_twig_broadcaster "https://github.com/symfony/ux-turbo/blob/3.x/src/Broadcaster/TwigBroadcaster.php"
click node_mercure_broadcaster "https://github.com/symfony/ux-turbo/blob/3.x/src/Bridge/Mercure/Broadcaster.php"
click node_stream_listen "https://github.com/symfony/ux-turbo/blob/3.x/src/Bridge/Mercure/TurboStreamListenRenderer.php"
click node_runtime "https://github.com/symfony/ux-turbo/blob/3.x/src/Twig/TurboRuntime.php"
click node_extension "https://github.com/symfony/ux-turbo/blob/3.x/src/DependencyInjection/TurboExtension.php"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_frame,node_request,node_stream_response,node_stream_helper,node_twig,node_templates,node_user toneBlue
class node_browser,node_mercure_source toneAmber
class node_doctrine,node_broadcast_attribute,node_broadcaster_interface,node_imux,node_twig_broadcaster,node_mercure_broadcaster toneMint
class node_stream_listen,node_runtime,node_extension toneRose
class node_controller,node_hub toneIndigo
```

## Components

### Symfony responses

- [Frame handling](https://github.com/symfony/ux-turbo/blob/3.x/src/TurboFrame.php): `src/TurboFrame.php`
- [Request listener](https://github.com/symfony/ux-turbo/blob/3.x/src/Request/RequestListener.php): `src/Request/RequestListener.php`
- [Stream response](https://github.com/symfony/ux-turbo/blob/3.x/src/TurboStreamResponse.php): `src/TurboStreamResponse.php`
- [Stream markup](https://github.com/symfony/ux-turbo/blob/3.x/src/Helper/TurboStream.php): `src/Helper/TurboStream.php`
- [Twig helpers](https://github.com/symfony/ux-turbo/tree/3.x/src/Twig): `src/Twig`
- [Turbo templates](https://github.com/symfony/ux-turbo/tree/3.x/templates/components): `templates/components`

### Browser Turbo

- [Turbo browser](https://github.com/symfony/ux-turbo/tree/3.x/assets/src): `assets/src`
- [Mercure stream source](https://github.com/symfony/ux-turbo/blob/3.x/src/Bridge/Mercure/MercureStreamSourceRenderer.php): `src/Bridge/Mercure/MercureStreamSourceRenderer.php`

### Entity broadcasts

- [Doctrine lifecycle](https://github.com/symfony/ux-turbo/blob/3.x/src/Doctrine/BroadcastListener.php): `src/Doctrine/BroadcastListener.php`
- [Broadcast settings](https://github.com/symfony/ux-turbo/blob/3.x/src/Attribute/Broadcast.php): `src/Attribute/Broadcast.php`
- [Broadcaster interface](https://github.com/symfony/ux-turbo/blob/3.x/src/Broadcaster/BroadcasterInterface.php): `src/Broadcaster/BroadcasterInterface.php`
- [Broadcaster dispatch](https://github.com/symfony/ux-turbo/blob/3.x/src/Broadcaster/ImuxBroadcaster.php): `src/Broadcaster/ImuxBroadcaster.php`
- [Twig action renderer](https://github.com/symfony/ux-turbo/blob/3.x/src/Broadcaster/TwigBroadcaster.php): `src/Broadcaster/TwigBroadcaster.php`
- [Mercure broadcaster](https://github.com/symfony/ux-turbo/blob/3.x/src/Bridge/Mercure/Broadcaster.php): `src/Bridge/Mercure/Broadcaster.php`

### Bundle integration

- [Mercure listen renderer](https://github.com/symfony/ux-turbo/blob/3.x/src/Bridge/Mercure/TurboStreamListenRenderer.php): `src/Bridge/Mercure/TurboStreamListenRenderer.php`
- [Twig runtime](https://github.com/symfony/ux-turbo/blob/3.x/src/Twig/TurboRuntime.php): `src/Twig/TurboRuntime.php`
- [Bundle configuration](https://github.com/symfony/ux-turbo/blob/3.x/src/DependencyInjection/TurboExtension.php): `src/DependencyInjection/TurboExtension.php`

### Other components

- **User**
- **Symfony controller**
- **Mercure hub**

## Connections

- User → Symfony controller: requests page
- Symfony controller → Frame handling: checks frame
- Symfony controller → Stream response: returns stream
- Stream response → Stream markup: builds markup
- Symfony controller → Twig helpers: renders page
- Twig helpers → Turbo templates: renders components
- Request listener → Symfony controller: sets request format
- Stream response → Turbo browser: returns stream HTML
- Turbo templates → Turbo browser: serves HTML
- Turbo browser → User: updates interface
- Doctrine lifecycle → Broadcast settings: reads settings
- Doctrine lifecycle → Broadcaster interface: broadcasts changes
- Broadcaster dispatch → Broadcaster interface: implements dispatch
- Twig action renderer → Broadcaster dispatch: decorates dispatch
- Twig action renderer → Mercure broadcaster: renders actions
- Mercure broadcaster → Mercure hub: publishes update
- Twig runtime → Mercure listen renderer: renders listener
- Twig runtime → Mercure stream source: renders source
- Mercure listen renderer → Turbo browser: provides listen markup
- Mercure stream source → Turbo browser: provides source markup
- Bundle configuration → Twig runtime: configures services
- Bundle configuration → Doctrine lifecycle: registers listener
