Remotion compatibility
What works when you render a Remotion project with Kinetograph, what happens to things the engine can't draw, and how to check a project first.
Kinetograph renders Remotion projects without a browser. Your remotion and @remotion/* imports run on Kinetograph's own version of those packages, and the engine draws every frame itself.
Most projects just work. When something can't be drawn, Kinetograph tells you. For a package-by-package list with export counts, and the steps to move a project, see Migrate from Remotion.
What happens to things the engine can't draw
The engine skips them or draws something close, and prints a warning. It never switches to a browser.
- Skipped: the frame is drawn without the item.
- Approximated: the frame is drawn with something close to the item.
- Warned: after drawing,
render,stillandstripprint one line for each kind of problem. Each line names the element, the property, the reason and the frames it happened on. At most 12 lines are shown, and nothing is printed if there were no problems.
The warning only appears on frames where the element is actually on screen. Elements with display: none or visibility: hidden are not checked.
Make unsupported content an error with --strict
render, still and strip accept --strict. With it, the first frame that has anything unsupported stops the command with the error code UNSUPPORTED_CONTENT. The error exits with code 1, names the frame, and lists up to five items. A render that stops this way leaves no output file.
Use --strict in CI and for final renders, so you never ship a video with something missing. Without it, you get a video that may be slightly off, which is often more useful while you work.
--strict does not compare your video with Chrome. It only checks whether anything unsupported was used.
Check a project before you render
kinetograph doctor <entry>goes through every frame without using the GPU. It reports what the engine can't draw and on which frames. Run it before a long render. If the project imports a package Kinetograph doesn't support, such as@remotion/three,doctorlists each import and the file that has it, and still checks the frames it can.kinetograph lintadds one warning per problem, with rulecompat. The frame still renders.- Both are also MCP tools. The
doctortool takes the same arguments, andstill,stripandrendertakestrict.
bench, onion and snapshot draw frames as they are and do not warn. The studio shows a frame's unsupported items as a warning.
What works
These packages and APIs are supported. Gaps are listed in Known issues.
@remotion/transitions: all 19 presentations anduseTransitionProgress.@remotion/light-leaks,@remotion/starburst,@remotion/sfx,zod-types,timeline-utils, andcanvas(Canvas 2D).@remotion/media-utilsaudio:getAudioData,useAudioData,useWindowedAudioData,getAudioDurationInSeconds,visualizeAudioandgetWaveformPortion.visualizeAudiofollows Remotion's documented behaviour, but its numbers are not identical.<Audio>and<Video>from@remotion/media.toneFrequencyon<Audio>and<Video>, from 0.01 to 2. It changes the pitch and keeps the length.@remotion/media-parserand@remotion/webcodecs: partly supported.@remotion/skiaand@remotion/rive: run through optional add-ons, with gaps.
Plain HTML and SVG elements can sit next to Kinetograph's own elements in the same tree. You don't switch compatibility on.
Things your project can use as it is
import './index.css'works. Local@imports in the file are inlined. Tailwind is built with your project's own Tailwind setup.*.module.cssfiles export their scoped class names.- The entry file runs even when
package.jsonhas a"sideEffects"list that leaves it out, as Remotion's templates do. staticFilereadspublic/next to the entry. If there is none, it readspublic/next to the nearestpackage.json, which is Remotion's rule when the entry is insrc/.- Fonts load from their files, whether you add them with
new FontFace(...)anddocument.fonts.add(face)or with an@font-facerule. One file is kept for each family, weight and style. If a font is split byunicodeRange, the part covering basic Latin is used. WOFF and WOFF2 files are unpacked. - Kinetograph reads no fonts from your system, so a render looks the same on every machine. If your project loads no font, text is drawn in DM Sans, a font that ships with Kinetograph, and the warning and
doctorsay so (font-family, "font not loaded; drawn with the built-in fallback"). SVG<text>is covered too.
Layout of HTML content
CSS lays out HTML content the same way a browser would, with a few rules to know:
- A group of HTML elements is laid out as a box the size of the composition, as Remotion's root
divis. - An
<AbsoluteFill>or<Sequence>around HTML is an absolutely positioned column flexdiv, as in Remotion. - HTML inside a Kinetograph layer is laid out in the composition's box. It does not know the layer's own size.
- A Kinetograph element inside HTML takes the size of its own box. A layer with no box, such as a group without
layout, is 0 × 0. - Styles are read on every frame, so animation comes from your component re-rendering, as in Remotion. CSS
@keyframesfollow the frame's time. - A layer made from an HTML node takes its
idattribute as its layer id if that is a valid id. Otherwise it gets where the node sits in the page, such as$0.2.