VideoFlowcodeGitHubTry itCoreRenderersReact Video EditorPlaygroundExamplesDocscodeGitHubTry it
Getting started
InstallationQuick startCore conceptsYour first video
Builder
Builder APITime formatsParallel & wait
Layers
TextImageVideoAudioCaptionsShapeGroups
Animation
Animate & keyframesEasing functionsTransitionsEffects
Renderers
Browser rendererServer rendererDOM preview
React Video Editor
QuickstartThemingUploadsCustom panelsHooks & commandsKeyboard shortcuts
API reference
Overview@videoflow/core@videoflow/renderer-browser@videoflow/renderer-server@videoflow/renderer-dom@videoflow/react-video-editor

Editor uploads

When the user drops a file into the timeline or the sidebar, the editor calls onUpload(file). Resolve the promise with a public URL and the editor uses that for all references — playback, rendering, caching.

Signature

type UploadHandler = (file: File) => Promise<string>;

S3 example

<VideoEditor
  video={v}
  onUpload={async (file) => {
    const { url, fields } = await fetch('/api/presigned', {
      method: 'POST',
      body: JSON.stringify({ name: file.name, type: file.type }),
    }).then((r) => r.json());

    const body = new FormData();
    Object.entries(fields).forEach(([k, v]) => body.append(k, v));
    body.append('file', file);

    await fetch(url, { method: 'POST', body });
    return `${url}/${fields.key}`;
  }}
/>

Cloudflare R2 / Supabase

<VideoEditor
  onUpload={async (file) => {
    const form = new FormData();
    form.append('file', file);
    const res = await fetch('/api/upload', { method: 'POST', body: form });
    const { url } = await res.json();
    return url;
  }}
/>

Fallback: object URLs

If you don't pass onUpload, the editor wraps dropped files with URL.createObjectURL() and revokes them on unmount. Great for demos — a dead end for anything persisted.

CORS. Whatever URL you return must be reachable with CORS enabled so the editor's renderer can decode it. S3 and R2 both need an explicit GET policy allowing your app origin.

VideoFlow

Open-source toolkit for composing videos from code.

Product

CoreRenderersReact Video EditorPlayground

Learn

DocsAPI referenceExamplesvs. Remotionvs. FFmpeg

Project

GitHubLicenseContactTermsPrivacy

From the blog

All posts →How to Automate Loom-style Product Demos with TypeScriptAutomated Podcast Audiogram Generator: Turning Audio into Viral Video with TypeScriptHow to Turn Markdown Changelogs into Automated Product Update VideosAutomating Personalized Onboarding Videos with VideoFlow and TypeScriptAutomating YouTube Shorts: Build a Vertical Video Factory in 30 Lines of TypeScriptCinematic 3D Video with TypeScript: A Guide to Perspective and RotationCinematic GLSL Effect Stacking: Building High-End Visuals with CodeDiffable Video: Versioning Your Media Pipeline with VideoJSON
© 2026 VideoFlow. Apache-2.0 core.