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}
Variable Type Description {config.addonName}string The name of the AIOStreams instance (ADDON_NAME env var)
Variable Type Description {stream.type}string Type: debrid, usenet, http, live, youtube, p2p {stream.proxied}boolean Whether the stream is proxied (e.g. MediaFlow) {stream.library}boolean Whether the file is already in your "library" e.g. debrid account {stream.indexer}string Source indexer {stream.message}string Additional status message {stream.infoHash}string Torrent info hash
Variable Type Description {stream.filename}string Filename of the stream or media file {stream.folderName}string Folder name (usually only specific addons) {stream.size}number File size in bytes {stream.folderSize}number Folder/torrent size in bytes {stream.bitrate}number Bitrate in bits per second {stream.duration}number Media duration in seconds {stream.container}string File container format (e.g. mkv, mp4) {stream.extension}string File extension (e.g. .mkv, .iso)
Variable Type Description {stream.quality}string Quality tag (e.g. Bluray, WEB-DL) {stream.resolution}string Video resolution (e.g. 1080p, 2160p) {stream.visualTags}string[] Visual tags (e.g. HDR, DV, HDR10+) {stream.encode}string Encoding format (e.g. HEVC, AVC, AV1) {stream.network}string Source network (e.g. Netflix, Disney+) {stream.hasChapters}boolean Whether the file contains chapters
Variable Type Description {stream.audioTags}string[] Audio tags (e.g. Atmos, DTS-HD MA, DD+) {stream.audioChannels}string[] Audio channels (e.g. 5.1, 7.1)
Variable Type Description {stream.languages}string[] Languages extracted from filename or audio track info {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 filtered to those you have configured (preferred, required, or included but not excluded){stream.uLanguageEmojis}string[] uLanguages as emoji flags{stream.uLanguageCodes}string[] uLanguages as ISO 639 codes{stream.uSmallLanguageCodes}string[] uLanguages as small-caps codes{stream.dubbed}boolean Whether the release is dubbed
Variable Type Description {stream.subtitles}string[] Embedded subtitle languages (when known — see note below) {stream.subtitleEmojis}string[] subtitles as emoji flags{stream.subtitleCodes}string[] subtitles as ISO 639 codes{stream.smallSubtitleCodes}string[] subtitles as small-caps codes{stream.uSubtitles}string[] subtitles filtered to those you have configured (preferred, required, or included but not excluded){stream.uSubtitleEmojis}string[] uSubtitles as emoji flags{stream.uSubtitleCodes}string[] uSubtitles as ISO 639 codes{stream.uSmallSubtitleCodes}string[] uSubtitles as small-caps codes{stream.subbed}boolean Whether the release has subtitles
languages vs subtitles
languages and subtitles behave differently depending on what information is available for a stream.
When accurate media info is available , languages contains audio track languages and subtitles contains embedded subtitle languages. This is the case for:
Debrid results from built-in and service-wrapped addons that have media_info from StremThru (crowdsourced/probed via FFmpeg)
Torznab/Newznab results from indexers that provide separate audio/subtitle metadata
nekoBT results (all results have accurate audio/subtitle info)
Torrentio anime results (subtitles field may be populated)
In all other cases , subtitles is empty and languages contains every language found in the filename — including subtitle-only languages (e.g. a filename containing Eng.Sub will add English to languages, not subtitles). This is a known limitation of filename-only parsing.
Variable Type Description {stream.title}string Media title extracted from filename {stream.year}string Year extracted from filename {stream.date}string Date extracted from filename {stream.releaseGroup}string Name of the release group {stream.editions}string[] Special editions (e.g. Director's Cut) {stream.repack}boolean Whether the release is a repack {stream.regraded}boolean Whether the content is regraded {stream.uncensored}boolean Whether the content is uncensored {stream.unrated}boolean Whether the content is unrated {stream.upscaled}boolean Whether the content has been upscaled
Variable Type Description {stream.seasonPack}boolean true if part of a season pack{stream.seasons}number[] Detected season numbers {stream.formattedSeasons}string Formatted season string (e.g. S01 or S01-05) {stream.folderSeasons}number[] Seasons from folder name (when different from filename) {stream.formattedFolderSeasons}string Formatted seasons from folder name {stream.episodes}number[] Detected episode numbers {stream.formattedEpisodes}string Formatted episode string (e.g. E01 or E01-05) {stream.folderEpisodes}number[] Episodes from folder name (when different from filename) {stream.formattedFolderEpisodes}string Formatted episodes from folder name {stream.seasonEpisode}string[] Pre-formatted season/episode strings (e.g. ['S01', 'E05'])
Variable Type Description {stream.seeders}number Torrent seeder count {stream.private}boolean true if from a private tracker{stream.freeleech}boolean true if the torrent is freeleech{stream.age}string Human-readable age since release {stream.ageHours}number Age in hours
Variable Type Description {stream.seadex}boolean Whether listed as best/alt on SeaDex {stream.seadexBest}boolean Whether listed as a best release on SeaDex
Variable Type Description {stream.regexMatched}string Name of the highest-priority matched preferred regex {stream.rankedRegexMatched}string[] All matched Ranked Regex Filter names (sorted) {stream.regexScore}number Score from matched Regex Filter {stream.nRegexScore}number Regex score normalised to 0–100 {stream.seScore}number Score from matched Stream Expression sort rule {stream.nSeScore}number Stream Expression score normalised to 0–100 {stream.seMatched}string Name of the Preferred Stream Expression that matched (from first comment) {stream.rseMatched}string[] Names of all Ranked Stream Expressions that matched
Variable Type Description {service.id}string Service identifier (e.g. realdebrid) {service.shortName}string Abbreviated name (e.g. RD) {service.name}string Full name (e.g. Real-Debrid) {service.cached}boolean Whether the stream is cached
Variable Type Description {addon.presetId}string The preset ID the addon was generated from {addon.name}string Display name of the addon {addon.manifestUrl}string The addon's manifest URL
Variable Type Description {metadata.queryType}string Media type being queried (movie, series, anime.series, or anime.movie) {metadata.title}string Title of the media being queried {metadata.runtime}number Movie runtime in minutes {metadata.episodeRuntime}number Episode runtime in minutes {metadata.genres}string[] List of genres {metadata.year}number Release year
Variable Type Description {debug.json}string Raw JSON of the stream data {debug.jsonf}string Pretty-printed JSON of the stream data
Modifier Description ::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
Modifier Description ::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
Modifier Description ::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
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}"||""]}
Modifier Description Types istrueValue is true booleanisfalseValue is false booleanexistsNot null, undefined, empty string, or empty array string, array, any$XStarts with X / first array element is X string, string[]^XEnds with X / last array element is X string, string[]~XContains X string, string[]=XExactly equal to X string, number>=XGreater than or equal to X number<=XLess than or equal to X number>XGreater than X number<XLess than X number
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"||""]}
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).
Operator Description 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}"||""]}
Use formatting tools with {tools.toolName}:
Tool Description {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}.
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.
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