upload-r2

$npx mdskill add remotion-dev/remotion/upload-r2

Uploads large Remotion assets to Cloudflare R2 and swaps local paths for hosted URLs.

  • Solves hosting large media files that exceed Git size limits or should avoid binary commits.
  • Depends on Bun's S3 client, Cloudflare R2 bucket, and credentials from the main worktree.
  • Locates the main worktree, loads credentials, and checks if the remote file already exists.
  • Uploads the file to the parser-media bucket and replaces local public/ assets with remotion.media URLs.

SKILL.md

.github/skills/upload-r2View on GitHub ↗
---
name: upload-r2
description: Upload large Remotion repository assets to the Cloudflare R2 bucket behind remotion.media and replace local public/ assets with hosted URLs. Use when a file is too large for Git or when a PR should avoid committing media binaries by hosting them on remotion.media.
---

# Upload R2 Asset

Use this for large media assets that should be hosted on `https://remotion.media/` instead of committed to Git.


## Workflow

1. Find the main worktree:
   ```bash
   git worktree list --porcelain
   ```
   Prefer the worktree on `refs/heads/main`, usually `/Users/jonathanburger/remotion`.

2. Load R2 credentials from the main worktree:
   ```bash
   --env-file=/Users/jonathanburger/remotion/packages/remotion-media/.env
   ```
   Do not print secret values. The required variables are `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`.

3. Upload the file to the `parser-media` bucket using Bun's S3-compatible client:
   ```bash
   bun --env-file=/Users/jonathanburger/remotion/packages/remotion-media/.env -e "import {S3Client} from 'bun'; const filePath='<local-file>'; const key='<remote-file-name>'; const client=new S3Client({accessKeyId:Bun.env.AWS_ACCESS_KEY_ID, secretAccessKey:Bun.env.AWS_SECRET_ACCESS_KEY, endpoint:'https://2fe488b3b0f4deee223aef7464784c46.r2.cloudflarestorage.com', bucket:'parser-media'}); const file=Bun.file(filePath); if (await client.exists(key)) { const stat=await client.stat(key); if (stat.size===file.size) { console.log('exists-same-size', key, file.size); process.exit(0); } } await client.write(key, file); const stat=await client.stat(key); console.log('uploaded', key, stat.size);"
   ```

4. Verify the public URL:
   ```bash
   curl -I --fail https://remotion.media/<remote-file-name>
   ```

5. Replace local asset usage with the hosted URL and delete the local binary.

   Do not wrap remote URLs in `staticFile()`: `staticFile()` rejects `http://` and `https://` URLs. Use the URL string directly, for example:
   ```tsx
   <Video src="https://remotion.media/example.mp4" />
   ```

6. Run the focused lint or stylecheck for touched packages, then commit and push.

More from remotion-dev/remotion

SkillDescription
add-bugAdd a new Remotion bug entry to packages/bugs/api/[v].ts. Use when the user describes a bug and affected Remotion versions that should be surfaced through the bugs API.
add-cli-optionAdd a new Remotion CLI or config option by creating an AnyRemotionOption, registering CLI parsing, wiring config setters, and updating documentation. Use when adding or converting command-line flags or Remotion options.
add-effectAdd a new effect to @remotion/effects, including implementation, package exports, docs, demos, preview images, Remotion skill updates, formatting, and builds.
add-expertAdd a new expert to the Remotion experts page
add-new-packageAdd a new package to the Remotion monorepo, including package scaffolding, monorepo registration, documentation, build scripts, and release checklist updates. Use when creating a new @remotion package.
add-sfxAdd a new sound effect to @remotion/sfx
add-webcodecs-bugAdd a browser WebCodecs bug to the Remotion Mediabunny WebCodecs bugs docs page. Use when given a Chromium, WebKit, or Firefox issue URL that should be tracked in packages/docs/docs/mediabunny/webcodecs-bugs.mdx, especially when needing to look up the issue title, filing date, reporter, and resolution state before editing the MDX table.
canvas-capture-extensionRebuild, install, and reload the private Remotion Canvas Capture unpacked Chrome extension. Use when the extension needs to be restored after a Codex worktree was deleted, rebuilt after source changes, moved to its durable install directory, or reloaded in Chrome or Chrome Canary.
checkoutCheckout a requested branch or ref in the Remotion repo, rename the current task to the associated PR title when running in Codex, then install dependencies and build. Use when the user asks to checkout a ref and prepare the workspace.
convertStart the local @remotion/convert app and open it in the Codex browser. Use when the user invokes /convert or $convert, asks to launch convert.remotion.dev locally, or wants to inspect the Convert package UI.