⚠️ These docs are currently under construction and may not be fully accurate.
AIOStreamsAIOStreams
Reference

Custom Formatter

Complete reference for formatting stream names and descriptions using variables, modifiers, and conditionals.

The Custom Formatter gives you full control over how each stream's name and description are displayed in Stremio (and other clients). You can live-preview your format on the configuration page using the Preview button.

Access a variable using:

{variableName.propertyName}

Modifiers are chained with :::

{variableName.propertyName::modifier}

Variables

Config

VariableTypeDescription
{config.addonName}stringThe name of the AIOStreams instance (ADDON_NAME env var)

Stream

VariableTypeDescription
{stream.proxied}booleanWhether the stream is proxied (e.g. MediaFlow)
{stream.type}stringType: debrid, usenet, http, live, youtube, p2p
{stream.filename}stringFilename of the stream or media file
{stream.folderName}stringFolder name (usually only specific addons)
{stream.size}numberFile size in bytes
{stream.bitrate}numberBitrate in bits per second
{stream.folderSize}numberFolder/torrent size in bytes
{stream.library}booleanWhether from a personal Debrid library
{stream.quality}stringQuality tag (e.g. Bluray, WEB-DL)
{stream.resolution}stringVideo resolution (e.g. 1080p, 2160p)
{stream.languages}string[]Available audio languages
{stream.seeders}numberTorrent seeder count
{stream.private}booleantrue if from a private tracker
{stream.freeleech}booleantrue if the torrent is freeleech
{stream.age}stringHuman-readable age since release
{stream.ageHours}numberAge in hours
{stream.duration}numberMedia duration in seconds
{stream.infoHash}stringTorrent info hash
{stream.message}stringAdditional status message
{stream.languageEmojis}string[]Languages as emoji flags
{stream.languageCodes}string[]Languages as ISO 639 codes
{stream.smallLanguageCodes}string[]Languages as small-caps codes
{stream.uLanguages}string[]Languages also in your language settings
{stream.uLanguageEmojis}string[]Same, as emoji flags
{stream.uLanguageCodes}string[]Same, as ISO 639 codes
{stream.uSmallLanguageCodes}string[]Same, as small-caps codes
{stream.visualTags}string[]Visual tags (e.g. HDR, DV, HDR10)
{stream.audioTags}string[]Audio tags (e.g. Atmos, DTS-HD MA)
{stream.audioChannels}string[]Detected audio channels (e.g. 5.1)
{stream.releaseGroup}stringName of the release group
{stream.encode}stringEncoding format (e.g. x264, HEVC)
{stream.editions}string[]Special editions (e.g. Director's Cut)
{stream.repack}booleanWhether the release is a repack
{stream.regraded}booleanWhether the content is regraded
{stream.uncensored}booleanWhether the content is uncensored
{stream.unrated}booleanWhether the content is unrated
{stream.upscaled}booleanWhether the content has been upscaled
{stream.network}stringSource network (e.g. Netflix, Disney+)
{stream.container}stringFile container format (e.g. mkv, mp4)
{stream.extension}stringFile extension (e.g. .mkv, .iso)
{stream.indexer}stringSource indexer
{stream.title}stringMedia title extracted from filename
{stream.year}stringYear extracted from filename
{stream.date}stringDate extracted from filename
{stream.seasonPack}booleantrue if part of a season pack
{stream.seasonEpisode}string[]Pre-formatted season/episode strings (e.g. ['S01', 'E05'])
{stream.seasons}number[]Detected season numbers
{stream.formattedSeasons}stringFormatted season string (e.g. S01 or S01-05)
{stream.folderSeasons}number[]Seasons from folder name (when different)
{stream.formattedFolderSeasons}stringFormatted seasons from folder name
{stream.episodes}number[]Detected episode numbers
{stream.formattedEpisodes}stringFormatted episode string (e.g. E01 or E01-05)
{stream.folderEpisodes}number[]Episodes from folder name (when different)
{stream.formattedFolderEpisodes}stringFormatted episodes from folder name
{stream.seadex}booleanWhether listed as best/alt on SeaDex
{stream.seadexBest}booleanWhether listed as a best release on SeaDex
{stream.regexMatched}stringName of the highest-priority matched preferred regex
{stream.rankedRegexMatched}string[]All matched Ranked Regex Filter names (sorted)
{stream.regexScore}numberScore from matched Regex Filter
{stream.nRegexScore}numberRegex score normalised to 0–100
{stream.seScore}numberScore from matched Stream Expression sort rule
{stream.nSeScore}numberStream Expression score normalised to 0–100
{stream.seMatched}stringName of the Preferred Stream Expression that matched (from first comment)
{stream.rseMatched}string[]Names of all Ranked Stream Expressions that matched

Service

VariableTypeDescription
{service.id}stringService identifier (e.g. realdebrid)
{service.shortName}stringAbbreviated name (e.g. RD)
{service.name}stringFull name (e.g. Real-Debrid)
{service.cached}booleanWhether the stream is cached

Addon

VariableTypeDescription
{addon.presetId}stringThe preset ID the addon was generated from
{addon.name}stringDisplay name of the addon
{addon.manifestUrl}stringThe addon's manifest URL

Metadata

VariableTypeDescription
{metadata.queryType}stringMedia type being queried (e.g. movie, series)
{metadata.title}stringTitle of the media being queried
{metadata.runtime}numberMovie runtime in minutes
{metadata.episodeRuntime}numberEpisode runtime in minutes
{metadata.genres}string[]List of genres
{metadata.year}numberRelease year

Debug

VariableTypeDescription
{debug.json}stringRaw JSON of the stream data
{debug.jsonf}stringPretty-printed JSON of the stream data

Modifiers

String Modifiers

ModifierDescription
::upperConvert to UPPERCASE
::lowerConvert to lowercase
::smallcapsConvert to ꜱᴍᴀʟʟ ᴄᴀᴘꜱ
::titleTitle Case (capitalise first letter of each word)
::replace('find', 'replaceWith')Replace all occurrences of find
::truncate(N)Truncate to N characters and append
::lengthReturn length of the string
::reverseReverse the string

Number Modifiers

ModifierDescription
::bytes / ::bytes10Format as base-10 bytes (KB, MB, GB)
::sbytes / ::sbytes10Concise base-10 byte format
::bytes2Format as base-2 bytes (KiB, MiB, GiB)
::sbytes2Concise base-2 byte format
::rbytes / ::rbytes10Like ::bytes but rounded
::rbytes2Like ::bytes2 but rounded
::bitrateFormat as bitrate (Kbps, Mbps)
::rbitrateLike ::bitrate but rounded
::sbitrateConcise bitrate (e.g. 5.2 Mbps)
::timeFormat seconds as 1h 30m
::starStar rating ★ out of 5 from a 0–100 score
::pstarPadded star rating (always 5 stars e.g. ★★★☆☆)
::hexEncode to hexadecimal
::octalEncode to octal
::binaryEncode to binary
::stringConvert to string

Array Modifiers

ModifierDescription
::join('separator')Join elements with separator
::slice(start, end)Return a section (end is optional)
::lengthNumber of elements
::firstFirst element
::lastLast element
::randomSingle random element
::sortSort (alphabetical for strings, numerical for numbers)
::rsortReverse sort
::lsortLexicographic sort (case-sensitive)
::reverseReverse order
::stringConvert to string

Conditional Modifiers

Conditionals evaluate to true or false and control what text is shown:

{variable.property::conditionalModifier["trueString"||"falseString"]}

Example: Show seeders only if greater than 1:

{stream.seeders::>1["Seeders: {stream.seeders}"||""]}
ModifierDescriptionTypes
istrueValue is trueboolean
isfalseValue is falseboolean
existsNot null, undefined, empty string, or empty arraystring, array, any
$XStarts with X / first array element is Xstring, string[]
^XEnds with X / last array element is Xstring, string[]
~XContains Xstring, string[]
=XExactly equal to Xstring, number
>=XGreater than or equal to Xnumber
<=XLess than or equal to Xnumber
>XGreater than Xnumber
<XLess than Xnumber

Both istrue and isfalse evaluate to false when the property is null or undefined. To handle true/false/null separately, chain two conditionals:

{service.cached::istrue["Cached"||""]}{service.cached::isfalse["Uncached"||""]}

Conditionals

Chain multiple conditions together using and, or, or xor:

{var1::cond1::or::var2::cond2["trueString"||"falseString"]}

Conditions are evaluated left to right: (x and y or z)((x and y) or z).

OperatorDescription
andBoth expressions must be true
orAt least one expression must be true
xorExactly one expression must be true

Example: Show seeders only when the stream is either uncached or a P2P torrent:

{service.cached::isfalse::or::stream.type::=p2p::and::stream.seeders::>0["Seeders: {stream.seeders}"||""]}

Tools

Use formatting tools with {tools.toolName}:

ToolDescription
{tools.newLine}Add a newline at this position
{tools.removeLine}Remove the entire line wherever found

{tools.newLine} works in the formatter preview but how it renders in Stremio is platform-dependent. Many platforms do not respect newlines in the name field. Avoid building your name template around {tools.newLine}.


Chillio

For Chillio, the name template maps to the ChillLink title field. The description template is split line-by-line into metadata strings — each line becomes a separate metadata entry.


Examples

Community-created formats are shared on the Discord Server.

You can also view the built-in formatter definitions at: packages/core/src/formatters/predefined.ts

On this page