Request-level App
A request-level App is scoped to a single request. It can send that specific request and read its live response, assertions, and test results.Enabling App Mode
App Mode replaces the request/response pane with your App view. From the Request Settings tab- Open the request and go to the Settings tab.
- Turn on the Enable App toggle.
- The App tab becomes visible, and the App view is set as the default for this request.

Adding an App to a request
- Open any request in Bruno.
- Click the App tab in the request panel.
- Write your HTML/JS in the code editor.
- Click on the Preview button to see the live preview.

What the App can do at request level
Collection-level App
A collection-level App is attached to an entire collection or folder. It opens as its own tab and can list and run any request inside the collection.Adding an App to a collection
- In the collection sidebar, right-click a collection or folder and choose New App from the context menu.

- A dialog box will open, enter a name for the App and click on the Create button.
- Write your HTML/JS in the code editor.
- Click on the Preview button to see the live preview.
When you create an App from a collection or folder, the default code provided lists all requests in that collection.

What the App can do at collection level
Collection-level Apps do not have access to
bru.ctx.http, bru.ctx.submitRequest, bru.ctx.assertions, or bru.ctx.tests. Those fields are only available on request-level Apps.Switching between Editor and App view
Both request and collection Apps have a split view:- Left pane - code editor with syntax highlighting and autocomplete.
- Right pane - live sandboxed render of the App.
Persistence
In-memory state (scroll position, local variables declared in script, etc.) is runtime-only and is lost when the App is reloaded or App Mode is toggled.
Tips
- Always do the first render inside
bru.ctx.onInit. Context data (response, variables, theme) arrives asynchronously after page load. Reading these at the top level returnsnullor empty values. - Reference variables as
{{name}}in the request. When you passruntimeVariablestosubmitRequestorrunRequest, Bruno interpolates the variable at runtime — it does not search-and-replace literal strings. - To persist a value between sends, use
bru.ctx.variables.runtime.set(name, value)instead of aruntimeVariablesoverride. Overrides are ephemeral and last only for the single send they are attached to. - Load external libraries from a CDN. Apps run outside Bruno’s strict CSP, so
<script src="…">tags pointing to unpkg, jsDelivr, or any CDN work without extra configuration.