Bruno API Client | Blog & News

How to Use Variable Types in Bruno v4: A Complete Guide

Written by Ganesh Patil | Aug 25, 2026

 

Variables are how Bruno keeps your API collections flexible. Instead of hard-coding a base URL, a token, or a timeout in every request, you define a variable once and reference it everywhere. Bruno v4 takes this further: variables can now be typed. A timeout can be a number, a feature flag can be a boolean, and a config block can be a full object not just strings. This guide covers the full variable system in Bruno and dives into the typed variable support introduced in v4, including the breaking change you need to know about before upgrading.

Table of Contents

What Are Variables in Bruno

A variable is a named value that Bruno substitutes into your requests at runtime. You reference a variable using double curly braces:

https://{{baseUrl}}/users/{{userId}} 

When Bruno runs that request, {{baseUrl}} and {{userId}} are replaced with their current values. If you change the base URL for staging, you update it in one place instead of every request that uses it.

Variables can appear in:

  • Request URLs, headers, query parameters, and body
  • Authentication fields (tokens, credentials)
  • Script values passed between requests
  • Pre-request and post-request scripts

Variable Types and Where They Live

Bruno has eight distinct variable categories. Each has a different scope and a different place it is defined:

Variable Type Where It Is Defined Typical Use
Global Environment Global environment settings Values shared across all collections
Environment <env-name>.yml Base URLs, tokens per environment (dev / staging / prod)
Collection opencollection.yml Defaults that apply to all requests in the collection
Folder <folder-name>.yml Shared values for a group of related requests
Request <request-name>.yml Values specific to a single request
Runtime Set in scripts at runtime Passing data between requests in a sequence
Prompt syntax Values you type in at the moment of each run (never stored)
Process Environment External .env file Injecting CI/CD or OS environment variables via

Data Types in Bruno v4 (Breaking Change)

Breaking change in v4.0.0: Bruno now supports typed variables. Collections that use @type(...) annotations will not parse in Bruno versions older than v4.0.0. If your team has members on v3, coordinate the upgrade before using typed variables in shared collections.

Before v4, every variable was a string. That meant sending a timeout value of 30 in a JSON body would arrive as "30" (a string) instead of the number 30. You had to cast it in a script. v4 removes that limitation.

Starting with v4.0.0, variables support four data types:

"text"

string

Default. No annotation needed.

42

number

Integers and decimals. Use @number

true

boolean

Feature flags, toggles. Use @boolean

{...}

object

Config blocks, nested data. Use @object

Type Annotation Example value Works across
string none required https://api.example.com All variable scopes
number @number 30 All variable scopes
boolean @boolean true All variable scopes
object @object { "host": "localhost" } All variable scopes

Backward compatible: Existing .bru files and environments that use plain string values continue to work without any changes. The @type annotation is only written when a non-string type is used.

YAML File Syntax for Typed Variables

In .yml files (used for workspace-level and environment configs), each typed variable is an object with a type field and a data field. Plain strings continue to use the flat name: value form — no change needed there.

number and boolean

runtime:
  variables:
    - name: timeout
      value:
        type: number
        data: "30"

    - name: debug
      value:
        type: boolean
        data: "true"

object and plain string

    - name: config
      value:
        type: object
        data: '{"host":"localhost","port":8080}'

    - name: baseUrl
      value: https://api.example.com
        # plain string — no type field needed

BRU vs YAML at a glance

Aspect BRU format YAML format
Type declaration Annotation on the line above: @number type: number field inside the value object
Object values Triple-quote block '''...''' Inline JSON string: '{"key":"val"}'
Plain string No annotation; just key: value Flat value: the-string

BRU File Syntax for Typed Variables

In .bru files, you declare a type by placing the annotation on the line immediately above the variable. Object values use a triple-quote (''') block to hold multi-line JSON.

number and boolean

vars:pre-request {
  @number
  timeout: 30

  @boolean
  debug: true

  baseUrl: https://api.example.com
}

object (triple-quote block)

vars:pre-request {
  @object
  config: '''
    {
      "host": "localhost",
      "port": 8080
    }
  '''
}

A full pre-request vars block combining all four types looks like this:

vars:pre-request {
  baseUrl: https://api.example.com   // string — no annotation

  @number
  timeout: 30

  @boolean
  featureFlag: true

  @object
  dbConfig: '''
    {
      "host": "localhost",
      "port": 5432
    }
  '''
}

The annotation must be on the line immediately above the variable, with no blank line between them. A blank line between @number and the variable name will cause it to be treated as a string.

Setting Typed Variables from Scripts

You can set typed variables from pre-request and post-request scripts using the same scripting API you already know. Bruno infers the type from the JavaScript value you pass and writes the correct annotation automatically — you do not need to specify a type manually.

// number — written with @number annotation
bru.setEnvVar("timeout", 30)

// boolean — written with @boolean annotation
bru.setEnvVar("debug", true)

// object — written with @object annotation
bru.setEnvVar("config", { host: "localhost", port: 8080 })

// string — written as plain string (no annotation)
bru.setEnvVar("baseUrl", "https://api.example.com")

When Bruno reads the variable back on the next request run, timeout resolves as a JavaScript number and config resolves as an object — not strings that need parsing. The type is preserved across runs.

Typed values work across all variable scopes from scripts. The same inference applies to:

Environment variables

bru.setEnvVar("retries", 3)
bru.setEnvVar("verbose", false)

Runtime variables

bru.setVar("userId", 101)
bru.setVar("isAdmin", true)

Debugging variables in the console

To inspect a variable value and its resolved type during a run, use the bru.get[Type]Var(key) pattern in a script:

// Runtime variable
console.log(bru.getVar('userId'))

// Environment variable
console.log(bru.getEnvVar('timeout'))

// Collection variable
console.log(bru.getCollectionVar('config'))

Prompt variables are not accessible via the Scripting API. They are entered by the user at the moment of the run and are never stored or readable from scripts.

Type Selector in the UI

You do not need to write annotations by hand. In the Vars tab of any request, folder, or environment, each variable row has a type dropdown to the right of the value field. Changing the type in the dropdown writes the correct annotation into the .yml file automatically.

Available options in the dropdown match the four supported types: string, number, boolean, and object. When you select object, the value field expands to accept a JSON block.

Quick Reference

Topic Details
Variable types (categories) Global, Environment, Collection, Folder, Request, Runtime, Prompt, Process Env
Supported data types (v4+) string (default), number, boolean, object
BRU annotation placement Line immediately above the variable: @number, @boolean, @object
YAML type declaration value: { type: number, data: "30" }
Breaking change Files with @type annotations will not parse in Bruno < v4.0.0
Script type inference bru.setEnvVar("key", 30) infers number automatically
Environment color coding Available since v3.1.0 — brush icon in environment settings
Documentation Variables Overview

Wrap Up

Variables are the foundation of any well-organised Bruno collection. They keep values in one place, let you switch environments instantly, and flow data between requests through scripts. Bruno v4 extends this with real data types: numbers stay numbers, booleans stay booleans, and objects stay objects — from the file on disk all the way through to the request body, without any casting or parsing in scripts.

The one thing to coordinate before adopting typed variables is the team upgrade: any .bru file with a @number, @boolean, or @object annotation will not open in Bruno versions before v4. Once your team is on v4, you get the full power of typed variables across all scopes, in both the BRU and YAML formats, and with automatic type inference from scripts.