Build a Descript alternative

Build a Descript alternative as an upload, transcript ranges, and an export. Hobbyist is $16 a month billed yearly. Avatars and Rooms stay on the long row.

  • getting-started
  • vibe-coding
  • scope

You can build a Descript alternative as an upload, transcript ranges, and an export. Descript is that product. The catalog line is “Delete a sentence. The audio goes with it.”

Hobbyist is $16 a person a month, billed annually. Business is $50 on that same annual billing. Monthly is $24 for Hobbyist and $65 for Business. Enterprise quotes are outside the note. The card scales with the team. The first estimate is 3 days, 24 hours. The verdict is “Cut the words, export”.

Last time I wrote about vibe coding your own Expensify. That was a teardown. This one is a regular backlog topic. AI avatars, a stock library, Rooms, and a brand studio stay on the skip row.

Build a Descript alternative from one recording

The Descript page splits the work into three rows.

The first row is 3 days. Upload, transcript ranges, delete-to-cut, and an export. You put the recording in. You mark the words you do not want. You download a file of what is left.

The second row is 2 weeks and up. A waveform, an undo stack, an SRT import, and one transcription API. A speech service can wait until a transcript you already have already cuts the file.

The third row is 3 months and up. AI avatars, a stock library, Rooms recording, and a team brand studio. The table labels that row as the part you should skip.

If you tell an agent to “clone Descript”, it aims at the third row. Copy the prompt, then pin it to the first one.

Store Project, MediaFile, TranscriptRange, EditAction, and ExportJob. The card names all five. For these 3 days, all five earn their place, and each one stays small. The waveform and the speech API do not.

A project is one episode, with a title. A media file is the original upload in object storage, and you never overwrite those bytes. A transcript range is a stretch of words with a start and an end, in milliseconds. An edit action is an ordered cut or restore, appended, not painted over the file. An export job is the new file built from the ranges you kept, plus a signed link.

The audience is a podcaster tightening one recording before it goes out. The goal on the card is to edit by deleting transcript ranges and export the cut. The same v1 also stands in for Riverside and CapCut. The card lists both and does not give them prices.

A tab recording and a share link is Loom at $15–$24 a month, in Vibe code your own Loom. Notes pinned to a timestamp, for someone else to approve, is Frame.io at $15–$25 a month. Trim, burned-in captions, and a download is Kapwing at $16–$50 a month. Those are different jobs. This one hides a sentence and gives you the file that remains.

The guardrail is the rule you paste into the prompt. Keep the original file immutable. Apply cuts as an ordered edit list. Sign every export URL.

Descript’s own edit-like-a-doc page says a delete takes the words out of the script and out of the media, and that the media is still there, hidden from the composition. Restore brings that span back. The 3-day clone copies that shape. It does not copy their aligner, their avatars, or Rooms.

How does a Descript alternative work

Nia has Ferry Notes, episode 14. The upload is a 22-minute stereo file. She already has the words, because she pasted them as ranges when she uploaded. Each range is text plus two integers. “The stall opens at seven” sits at 11800 ms to 12400 ms. The next range is “um, so, yeah” at 12400 ms to 14100 ms.

She selects that second range and deletes it. The app appends an edit action, cut, pointing at that range. The object in storage does not change. Playback asks the edit list which ranges are still live, and it skips 12400 to 14100. The listener hears “The stall opens at seven” and then whatever range follows.

Restore appends a second action. It does not delete the cut row. Play asks for the latest action per range. A full undo stack, with a waveform under the words, is the 2-week row. On this row, restore is one more line in the list.

Your browser talks to one Astro app. Node.js plus Astro is the default. Use TanStack Start if React is your weekday language. The capability line on the card is Astro, Alpine, and R2. A little client script moves the playhead and highlights the range that contains the current time. The list of ranges, the edit actions, and the file live on the server.

The transcription API is why a file with no words feels blocked. The card puts that API on the 2-week row, next to SRT import. If episode 14 arrives as audio only, Nia types the ranges she cares about, or she waits. She does not get a speech bill on the first build. SRT import is the same wait. A subtitle file is a list of ranges with timestamps, and parsing it is a day of edge cases once the hand-entered ranges already cut.

Export is a job, not a second copy made on every keystroke. She presses Export. The job reads the live ranges in time order, writes a new file of those spans, stores it beside the original, and returns a signed URL. The original key stays put. If the job fails, the edit list is still there and she runs it again. A guessed export URL returns nothing. The link dies.

Every query is scoped by owner. A project id from another account returns an empty page. The bucket is not public, and the player does not use a raw object URL.

Store 12.4 seconds as 12400. A float drifts once you add spans. The duration of a kept range is end minus start, and the export is the sum of the live ones. Same habit as the cents on a receipt.

Screens of a Descript alternative

v1 needs the transcript and the export. A waveform under the words can wait. A record button that opens a live room can wait with it.

The transcript

The screen is the episode title, the ranges in order, and the playhead. Ferry Notes, episode 14. One range is marked cut. Play skips it. Delete and Restore are the only edits.

WIREFRAME · TRANSCRIPT Ferry Notes · episode 14 11800–12400 · The stall opens at seven 12400–14100 · um, so, yeah · cut 14100–16800 · Bring a bag Play Delete Restore
The cut is a row. The upload in storage still has the "um".

The export

The export screen is the job. Original duration, kept duration, and a download once the job finishes. The kept duration is the sum of the live ranges. Episode 14 loses 1.7 seconds, which is 14100 minus 12400, and nothing else.

WIREFRAME · EXPORT Original · untouched in storage Kept · live ranges only · minus 1700 ms Download
Download is a new file. The link is signed, and it expires.

How a cut becomes a file

Nia uploads episode 14 and the ranges. The Astro app writes the bytes to R2 and the ranges to the database in one go. If the rows fail, she should not have an orphan object with no project. If the upload fails, she should not have ranges that point at a file she cannot open.

She cuts “um, so, yeah”. That is one insert into the edit list. She plays from the start of the sentence. The highlight follows the live range. The playhead time is the original file’s clock, with cut spans jumped over, so a later restore lands on the same milliseconds.

She exports. The job concatenates live ranges in order. They already met at 12400 and 14100, so the join is those two edges, with no extra silence written in. A pop at the join is a reason to nudge the edges later, on the waveform row, while the original stays as it was.

On the 2-week row she can import an SRT, call one speech API when a file has no words, and undo through a stack while looking at the wave. One provider is enough there. A second vendor, speaker labels, and a dictionary are how that row grows into the month.

NIA UPLOADS EPISODE 14 Audio file plus ranges in milliseconds ASTRO STORES BOTH Original bytes stay immutable SHE CUTS ONE RANGE 12400 to 14100 · um, so, yeah EXPORT JOB New file of the live ranges Signed link, original untouched
Three days ends at a file she can publish. The master recording is still in the bucket.
NIA'S BROWSER Upload, ranges, cut, export ASTRO APP Owner scope. Edit list is append-only. R2 ORIGINAL, DB RANGES Export is a second file, signed LATER, THEN SKIP Waveform, undo stack, SRT import One transcription API Avatars, stock, Rooms, brand studio Multi-track mixing
The original and the edit list are the whole v1. The studio features sit in the dashed box.

Where a Descript alternative gets hard

The 3-day cut is checkable on one laptop. Upload episode 14, delete one range, export, and the download should be 1700 ms shorter. Restore, export again, and the length should match the original. The master object hash should be unchanged after both jobs.

The speech API is the 2-week row because the words have to land on the audio. Descript’s help page is about editing a transcript that is already tied to the media. Their wordbar article is the tool for when a word’s start or end is wrong, down at the waveform. A transcript that is off by half a second cuts the wrong syllable. Fixing that by hand, per word, is the undo-and-wave work. Calling a provider and trusting the first JSON is how a demo looks done and the export sounds clipped.

Avatars, stock, Rooms, and a brand studio are the month row the card tells you to skip. Rooms is a live recording product. A stock library is a license catalog. An avatar is a generated person. Multi-track mixing is a studio. The non-goal names all of that, and it points tab recording at Loom.

The scope post is the same three-row habit. The prompt post is where you paste the immutable-original rule so the agent does not “clean up” the master file after each cut.

Start with the first row

Go to Build your own Descript. Copy the Astro prompt, or TanStack Start if that is what you write.

Tell the agent the first estimate only. Upload, transcript ranges, delete-to-cut, export. Three days.

Cut “um, so, yeah” on episode 14, download the file, and confirm the original object did not change. If you need the waveform, a speech API, or an avatar, keep the $16 plan for that part.

Keep reading

Read all articles →