How to optimise a video for the x / twitter algorithm
- Step 1Make the content autoplay-friendly first — X autoplays muted. Before formatting, make sure the first second reads without sound and any spoken content has on-screen text. Burn captions with the subtitle-burner — the formatter shapes the file, it can't add captions.
- Step 2Drop your clip into the X formatter — Drag an
.mp4,.mov,.mkv,.webm,.avi,.m4v, or.tsfile in. The card shows resolution and length so you can confirm the hook is in the kept centre region and the clip is within 2:20. - Step 3Run the formatter — Click Run X Format. No tuning needed — the pass is fixed at 720p H.264 CRF 20, AAC 128k, +faststart, 16:9 centre crop, 2:20 cap. The note confirms the AAC re-encode.
- Step 4Let it produce a native-ready MP4 — FFmpeg.wasm crops to 16:9, scales to 1280×720, caps at 140s, encodes
libx264 -crf 20 -pix_fmt yuv420p+aac 128k, and muxes+faststart. One MP4 out, optimised for fast first-frame playback. - Step 5Add a poster frame if you want one — Pull a strong still with the thumbnail-extractor to use as your post's first impression. The formatter doesn't set a poster frame — X uses the first frame, so make frame one count.
- Step 6Upload natively to X and watch the early signals — Attach the MP4 directly (never as a link). Native autoplay + +faststart give the clip the best shot at the watch-time and completion signals X ranks. Reach still depends on content and timing — the file is just the part you can control.
File-level signals the formatter controls (and the ones it can't)
The formatter optimises the file; reach also depends on content the formatter can't touch. Settings verified against lib/video/video-processor.ts.
| Signal | Controlled by formatter? | How |
|---|---|---|
| Native vs linked | Yes (enables it) | Produces an MP4 you upload natively — the autoplay path X favours |
| Fast first-frame playback | Yes | +faststart moves moov atom to the front |
| Decodes on all clients | Yes | H.264 yuv420p + AAC — universally decodable |
| No black bars (full card) | Yes | Center-crop to 16:9 |
| Within native length limit | Yes | 2:20 cap (-t 140) |
| Hook / first-second content | No | Your edit — make frame one work muted |
| On-screen captions | No | Use the subtitle-burner |
| Poster / thumbnail choice | No (X uses frame 1) | Pull a still with thumbnail-extractor |
Companion tools for an X-optimised post
Pair the formatter with these to cover the content signals it doesn't handle.
| Need | Tool |
|---|---|
| Captions for muted autoplay | subtitle-burner |
| A strong poster still | thumbnail-extractor |
| Cut to the best 2:20 segment | lossless-trimmer |
| Keep file small on mobile data | whatsapp-compressor |
| A 9:16 cross-post for Shorts | youtube-shorts-formatter |
Free-vs-paid limits for this tool
From the shared video tier family (lib/tier-limits.ts). One file per job; paid tiers batch sequentially.
| Tier | Max file size | Batch files / job |
|---|---|---|
| Free | 1 GB | 1 |
| Pro | 10 GB | 5 |
| Pro + Media | 100 GB | 50 |
| Developer | 100 GB | Unlimited |
Cookbook
Real prep workflows that combine the formatter with the file-level signals X actually reads. The formatter handles the encode; the companion steps handle the content.
Captioned, native, fast-start clip
The full autoplay-optimised pipeline: burn captions for muted viewing, then format to X spec so it plays instantly as a native upload.
1) subtitle-burner: hardsub captions (.srt) 2) twitter-x-formatter: crop 16:9 -> 1280x720, crf 20, aac 128k +faststart (instant play) -> native MP4, plays muted with on-screen text
+faststart is the watch-time lever
Without faststart, a player must download the moov atom (often at the end of the file) before playback starts — a stall that costs early watch time. The formatter always writes +faststart, so playback begins on the first received bytes.
No faststart : download moov (end) -> THEN play
(stall = lost early watch time)
Formatter : -movflags +faststart
moov at front -> plays immediately
Early play -> better completion signal.Native upload vs linked video
A YouTube link in a tweet shows a static card and doesn't autoplay, so it earns little watch time. The same clip uploaded natively (after formatting) autoplays in-feed. Format, then upload the file — don't paste a link.
Linked : tweet + youtube.com/... -> static card
no autoplay, low dwell
Native : upload the formatted MP4 directly
autoplays muted in feed
Formatter output is meant for the native path.Hook lives in frame one — pull it as the poster
X uses the first frame as the poster. Make sure frame one is a strong, legible hook, then extract it as a still for your own records or to verify it reads at thumbnail size.
thumbnail-extractor on the formatted MP4 interval 0s -> grab the first frame Check it reads as a hook at small size. (The formatter doesn't set a poster; X uses frame 1.)
Trim to the strongest 2:20, then optimise
Reach favours completion, so shorter and tighter often wins. Cut to your strongest segment under 2:20 first (lossless), then format — rather than letting the formatter keep an arbitrary opening 2:20.
1) lossless-trimmer: keep the best 90s (stream copy, no quality loss) 2) twitter-x-formatter -> native 720p MP4 Tighter clip -> higher completion -> better ranking signal.
Edge cases and what actually happens
Expecting the tool to boost reach directly
Not possibleNo tool can guarantee X reach — ranking weighs content, engagement, timing, and account signals. The formatter only optimises the file (native-ready, fast-start, decodable, full-card). Treat it as removing technical friction, not as a growth hack.
Want captions burned in
Different toolThe formatter can't add captions — critical for muted autoplay. Burn them first with the subtitle-burner, then format the captioned clip.
Want a custom thumbnail / poster
Not availableX uses the first frame as the poster, and the formatter has no poster-frame option. Make frame one a strong hook; use the thumbnail-extractor to verify how it reads.
Hook is in the cropped-off edges
By designThe center crop discards the edges (and, for portrait sources, the top/bottom). If your hook text sits there, it's gone after formatting. Pre-crop with the video-cropper to centre it first.
Posting as a link instead of native
Defeats the purposeThe formatter's whole value is feeding X a clean native upload. Pasting a link to the file (or to another platform) skips autoplay and the watch-time signal. Always attach the MP4 directly in the composer.
Clip over 2:20
Trimmed to 140sThe pass caps length at 140 seconds (X's native limit). For a chosen segment, trim first with the lossless-trimmer.
Output too large to upload
PossibleCRF 20 720p high-motion content can approach X's 512 MB cap. A failed upload kills the post entirely. Run a size-targeted compressor (whatsapp-compressor / discord-compressor) if needed.
Silent clip with no on-screen text
Weak for autoplayThe formatter produces a valid file, but a silent clip with nothing on screen won't hold a muted viewer. This is a content issue, not a file one — add captions or graphics before formatting.
Source dimensions unreadable
ErrorIf the file can't be probed the run fails with "Could not determine video dimensions." Re-mux via the video-transcoder first.
Batch-optimise a campaign of clips
SequentialPaid tiers run several clips one after another, each to the same native spec. Free tier does one at a time. The encode settings are identical per file.
Frequently asked questions
Can this tool make my video go further in X's algorithm?
It removes technical friction — native-ready encode, +faststart for instant playback, full-card 16:9, within the 2:20 limit — which protects the watch-time and completion signals X ranks on. It can't write your hook or guarantee reach; that's content, not encoding.
Why does native video do better than a YouTube link?
Native uploads autoplay muted in-feed and earn watch time; link cards are static and don't autoplay, so they bleed engagement. The formatter outputs a file built for the native path — upload it directly, don't paste a link.
What is +faststart and why does it matter for ranking?
It moves the MP4 moov atom to the front so the clip plays during download rather than after. Faster first-frame playback means fewer viewers scroll away before it starts — protecting the early watch-time signal. The formatter always applies it.
Does the formatter add captions for muted autoplay?
No. X autoplays muted, so captions matter, but you add them first with the subtitle-burner, then run the formatter on the captioned clip.
Can I set a custom thumbnail?
Not in this tool — X uses the first frame as the poster, and there's no poster option. Make frame one a strong hook; use the thumbnail-extractor to check how it reads at small size.
What exact encode does it use?
1280×720, libx264 -preset medium -crf 20 -pix_fmt yuv420p, audio aac -b:a 128k, MP4 with +faststart. All fixed — there are no quality or bitrate controls.
Should I keep clips short for better reach?
Often yes — completion rate is a strong signal, and shorter clips complete more. Trim to your tightest segment under 2:20 first with the lossless-trimmer, then format, rather than relying on the automatic opening-2:20 cut.
Will a 4K source rank better?
No — X delivers around 720p on most clients anyway, and uploading 4K just forces more re-encoding. Handing X a clean 720p file (what this formatter makes) is the practical optimum.
What input formats are accepted?
MP4, MOV, MKV, WebM, AVI, M4V, and TS. Output is always 1280×720 MP4.
Is anything uploaded while I prep the file?
No. The encode runs in-browser via FFmpeg.wasm — the clip stays local until you choose to post it natively. Only an anonymous processed-count is logged for signed-in dashboards.
Can I prep a batch of campaign clips?
Paid tiers batch: Pro 5, Pro + Media 50, Developer unlimited files per job (sequential). Free does one at a time. Every clip gets the identical native-ready spec.
Does it help with cross-posting to Shorts or Reels?
This formatter is 16:9 for X. For a 9:16 cross-post use the youtube-shorts-formatter; for 1:1 / 4:5 use the instagram-feed-formatter.
Privacy first
Every JAD Video tool runs entirely in your browser via WebCodecs and FFmpeg (WebAssembly). Your video files never leave your device — verified by zero outbound network requests during processing.