SRT vs VTT: which subtitle format should you use?

The differences between SubRip and WebVTT that actually matter, how to convert between them, and which one to pick for the web, for broadcast and for translation.

Short answer: use WebVTT if the video plays in a browser, and SubRip if it plays anywhere else. HTML5’s <track> element accepts only VTT, and almost every other player on earth accepts SRT.

The two formats are close relatives — VTT was designed as a web-native evolution of SRT and kept its shape — so the conversion is trivial and the choice is rarely irreversible. What follows is what actually differs, and when the difference matters.

SubRip (.srt)

The oldest and most widely supported subtitle format, and about as simple as a file format gets: a numbered list of cues, each with a start time, an end time, and one or more lines of text.

1
00:00:00,580 --> 00:00:04,270
In the last video, we showed
that if you had a line, which

2
00:00:04,270 --> 00:00:09,020
we'll call a directrix--
we draw the directrix.
  • Sequence numbers, starting at 1
  • Timecodes as HH:MM:SS,mmm --> HH:MM:SS,mmm — note the comma before milliseconds
  • Text on the following lines, which may wrap
  • A blank line between entries

There is no official specification. SRT is defined by what SubRip wrote and what every player since has agreed to accept, which is why the tolerated variations — inline <i> and <b> tags, occasional positioning coordinates, missing sequence numbers — vary by player.

WebVTT (.vtt)

A W3C format built for HTML5 video. Same cue-list idea, with a header and a real specification behind it.

WEBVTT

STYLE
::cue {
  background-color: transparent;
  color: white;
}

NOTE Keep this under two lines for the mobile player

intro
00:00:00.000 --> 00:00:04.000 position:50% align:center
Welcome to this video tutorial

00:00:04.000 --> 00:00:08.500 line:90%
In this section, we'll explore
the key concepts you need to know
  • A mandatory WEBVTT first line
  • Timecodes with a dot before milliseconds
  • Optional cue identifiers (intro above) instead of, or as well as, sequence numbers
  • Cue settings after the timecode for position, alignment and line placement
  • STYLE blocks carrying CSS that applies through the ::cue pseudo-element
  • REGION blocks defining scrollable areas, used for roll-up captions
  • NOTE blocks — comments that never render

The differences that matter

SubRip .srt WebVTT .vtt
Specification de facto W3C standard
Header line none WEBVTT required
Millisecond separator comma , dot .
Cue identifiers sequence numbers optional named identifiers
HTML5 <track>
Styling ad-hoc <i>/<b> by convention CSS via STYLE and ::cue
Positioning ✗ (non-standard extensions only) cue settings: position, line, align, size
Regions / roll-up
Comments NOTE blocks
Chapters and metadata tracks
Encoding unspecified, in practice a mess UTF-8 required
Player support near-universal browsers, and most modern players

Two rows carry most of the practical weight.

Encoding. SRT has no declared encoding, so files arrive in Windows-1252, Latin-1, Shift-JIS or UTF-8 with no way to tell except guessing. This is the origin of the mojibake you have seen in downloaded subtitles. WebVTT mandates UTF-8, and that single constraint removes an entire category of problem from a localization pipeline.

Comments. NOTE blocks are the only place in either format to leave an instruction for a translator — this is a brand name, do not translate, or keep under 40 characters, it overlaps the lower third. SRT has nowhere to put that, so the guidance ends up in an email and then nowhere.

Converting SRT to VTT

Two mechanical edits:

  1. Prepend WEBVTT and a blank line.
  2. Replace the comma before milliseconds with a dot, in timecode lines only.

Sequence numbers can stay — VTT reads them as cue identifiers.

bash
# Prepend the header, then fix the timecode separator
{ printf 'WEBVTT\n\n'; sed -E 's/([0-9]{2}:[0-9]{2}:[0-9]{2}),([0-9]{3})/\1.\2/g' input.srt; } > output.vtt

Going the other way is lossier, because everything VTT adds has to be dropped: styles, regions, cue settings and NOTE blocks have no SRT equivalent. Convert VTT → SRT only when a player forces you to, and keep the VTT as the source of truth.

What goes wrong in practice

Neither format has much surface area, so the failure modes are few and repetitive.

Byte order marks. An SRT saved from Notepad or exported by some Windows tooling starts with a UTF-8 BOM. Many players treat the BOM as part of the first cue’s sequence number, and cue 1 silently never displays. In VTT the same BOM breaks the WEBVTT header check and the whole file is rejected.

Overlapping and out-of-order cues. Both formats assume cues are in ascending time order and, in most players, non-overlapping. Editing tools that let you drag cues around will happily produce a file where cue 12 starts before cue 11 ends. Players disagree about what to do — some show both, some drop one, some stop rendering entirely.

Line endings. SRT’s entry separator is a blank line, so a file with mixed \r\n and \n endings can produce a “blank” line that is not blank. This is the classic symptom of a file that has been through a Windows editor and a Unix pipeline.

The --> arrow. It is exactly two hyphens and a greater-than sign, with a space on each side. A smart-quotes-style editor that converts the double hyphen into an em dash produces a file no parser will read, and the damage is invisible in a proportional font.

Timecode digits. SRT wants two-digit hours (00:01:02,500); VTT permits the hour to be omitted entirely (01:02.500). A converter that assumes one convention on input from the other will produce cues an hour out.

Most of these are worth catching with a parse step in CI rather than in review, because every one of them looks fine to a human reading the file.

Which to choose

Choose WebVTT if the video plays in a browser (it is the only option), you need captions positioned away from the default lower centre, you want CSS control over appearance, you are shipping chapters or metadata cues, or you want to carry translator instructions in the file itself.

Choose SubRip if you are targeting hardware players, older desktop players, or platforms that only accept SRT uploads; if you need the broadest possible compatibility with the least possible thought; or if the subtitles are an interchange artefact between tools rather than a delivery format.

Choose neither if you are delivering to broadcast or a major streaming platform. That world runs on TTML/DFXP, which is XML-based and carries the styling and timing metadata those workflows require.

In practice many teams keep an SRT master because it is the easiest thing to edit and review, and generate VTT at build time for the web player. That is a reasonable pipeline as long as the direction is one-way.

Translating either one

The text in both formats is plain, unescaped and unstructured, which makes them easy to translate and easy to break. Three things to watch:

Timings do not move. A translated cue has to fit the original time window. German and Finnish routinely run 20–30% longer than English; the translator needs to compress rather than translate literally, and needs to know that up front. This is a briefing problem, not a tooling one.

Line breaks are content. A two-line cue that becomes three lines will overflow the safe area on some players. Where the break falls also affects readability — breaking at a phrase boundary reads far better than breaking at the width limit.

Reading speed is a constraint. Roughly 15–20 characters per second is the usual comfortable ceiling for adult viewers. A cue on screen for two seconds has room for about 35 characters, whatever the translator would prefer to say.

WebTranslateIt reads and writes both formats, exposing only the subtitle text as translatable segments while timecodes, cue identifiers, styles and regions round-trip untouched. VTT NOTE blocks are carried through as developer comments, so a note written for the translator reaches them in the editor instead of being lost in the file. On the SRT side, the character counter and character limits are the practical tool for the reading-speed constraint: set a per-segment limit and the editor enforces it while the translator types.

Frequently asked questions

What is the difference between SRT and VTT?
WebVTT is a superset of SubRip in practice. Both are plain-text cue lists with timecodes, but VTT starts with a WEBVTT header, uses a dot before milliseconds instead of a comma, and adds styling, positioning, regions, comments, chapters and metadata. SRT has none of those and is correspondingly universal.
Can I just rename a .srt file to .vtt?
No. Renaming does not add the required WEBVTT header line, and the millisecond separator is still a comma, which a strict VTT parser rejects. The conversion is two mechanical edits — prepend WEBVTT and a blank line, and change the comma before milliseconds to a dot — but it does have to be done.
Does HTML5 video support SRT?
No. The <track> element requires WebVTT. Browsers will not render an SRT file passed to it. This is the single most common reason teams convert, and it is why any web video pipeline ends up producing VTT even when the source is SRT.
Which format is better for translation?
Both translate equally well because the text is plain in each. VTT is slightly better in practice because its NOTE blocks can carry instructions to the translator, which SRT has no way to express. What matters more than the format is that the tool preserves timings and cue identity while only exposing the text.

Keep reading

Translate your app without the spreadsheet round-trip

WebTranslateIt reads the file formats and placeholder syntax described on this page, validates them as translators work, and syncs the results straight back into your repository.