All projects

React · Developer Tooling

Kutlass

A drop-in React component that puts a full video editor inside your app. Published on npm, runs entirely in the browser.

Live 2025 Creator
kutlass.vercel.app
The Kutlass landing page, with the editor mounted below the headline showing a tool rail of Trim, Crop, Finetune, Filter, Speed, and Audio.
The demo page mounts the real component. The tool rail on the left is the whole editor surface.

Overview

What it is

Kutlass is an embeddable video editor for React apps. One component gives you trim, crop, speed, per-clip audio, filters, annotations, text and stickers, and export, with no backend behind it.

Export presets do the choosing for you. Reel, Story, Square, YouTube, X, and WebM each set format, resolution, frame rate, and crop together, so the common case is one click instead of six correct decisions.

Motivation

Why I built it

WebCodecs shipped and I wanted to find out how far it went. The question was how much of a real editing pipeline the browser could carry on its own.

The thing that kept me going was that the alternative for a small edit is genuinely bad. Trimming ten seconds off a clip should not require a desktop install or an upload to somebody else server, and for a React product there was no drop-in that avoided both.

Keeping the footage on the device was a nice property rather than the goal. It falls out of the architecture for free once you decide there is no backend.

Decisions

How it works

01

Edits are a list of operations, not pixels

Every cut, crop, filter, and annotation is an ordered operation. Preview replays the list, and only export materializes it. That is also why undo and redo across the full history are close to free rather than a snapshot problem.

02

WebCodecs first, FFmpeg WASM behind it

WebCodecs gets hardware decode and encode where the browser supports the codec. Anything it will not do falls to FFmpeg in a Web Worker, so a slow filter never blocks the interface. The editor probes what is available at runtime rather than sniffing the user agent.

03

Frames stream in chunks

The editor never holds a fully decoded file in memory. Frames move through the pipeline in groups, which is the only reason longer clips and multi-clip exports work at all in a tab.

Friction

What was hard

The codec support matrix

WebCodecs support varies by browser and by codec, and the failure mode is silence rather than an error. Runtime probing plus a WASM fallback covers it, but testing that matrix honestly is tedious and I have not covered all of it.

Keeping the WASM payload sane

A full FFmpeg build is enormous. This one is trimmed to the formats and filters the editor actually uses and loaded lazily, so mounting the component does not pull it. It is still the largest thing in the bundle by a wide margin.

Audio drifting away from video

Seek, trim, speed from 0.25x to 4x, and export each give timestamps a chance to slip. Most of the debugging time on this project went into sync, and it is the part I would rewrite first.

The state of it

Where it stands

The limitations, in plain terms. Every project here is something I built and use, not something I am selling.

Stack

React WebCodecs FFmpeg WASM Web Workers Canvas TypeScript

It is built for short clips. Long files and 4K will push a tab harder than is comfortable, and memory is the first thing to give.

It is not a replacement for a real editor. There is no multi-track timeline, no keyframing, and no colour grading.

Export speed depends entirely on whether WebCodecs will take your codec. On the WASM path it is a lot slower.

Next project

A11y Auditor