Skip to main content
← Back to blogs

Summarizing YouTube podcasts with Claude

AINext.jsWeb App

I watch podcasts across tech, football, and business, and a week later I can barely recall the key points. So I rebuilt my summarizer around Claude Opus 4.8: paste a YouTube link, and it reads the real captions and writes a structured, searchable article. It runs in the cloud with my computer off.

Every week I watch podcasts across tech, football, and business. I listen while commuting, while cooking, while going through my morning routine. Then, a week later, I am in a conversation where the topic comes up, and I cannot remember the key points. I know the podcast covered it. I know the guest said something worth repeating. But the details are gone.

I wanted a way to quickly scan what a podcast covered before a conversation. Something that gave me the structure: what was talked about, what the key arguments were, a few direct quotes. Existing tools do not solve this well. Podcast apps have transcripts, but transcripts are not readable. They are walls of spoken-word text with no hierarchy. Generic AI search gives you generic answers. Written summaries, when they exist at all, are either padded fluff or nowhere to be found.

I built the first version a while ago. It worked, but the summaries were thin, and it leaned on a model that guessed at the content rather than reading it. So I rebuilt it around Claude.

What it does

The tool is simple. You paste a YouTube URL. Claude reads the episode's real captions and writes a structured article: a one-line lede, several themed sections that follow the episode's actual arc, one woven quote per major topic, a short list of key takeaways, and tags. The output is not a recap. It is a readable piece you can scan in five minutes. The library grows over time, so every podcast you have processed is searchable.

There is a public showcase anyone can browse, and once you sign in you get your own private library. You paste a link, the card shows up as generating, and it fills itself in when the summary is ready. You do not have to keep the tab open.

The AI part: Claude Opus 4.8

The model is claude-opus-4-8. The important change from the old version is the input. Instead of asking a model to find a podcast and summarize it from whatever it could dig up, I feed Claude the episode's actual transcript, pulled from YouTube's caption track. When captions are missing, it falls back to Claude's web search tool. Real words in means a real summary out.

The other half is the prompt. Without constraints, AI summaries are generic. "The speakers discussed the challenges of X" is useless. It tells you nothing you could not have guessed from the title. So the prompt sets a real depth bar: 1,500 to 2,200 words, a dynamic number of sections that follow the episode's chapters, full narrative paragraphs rather than bullet points, and one verbatim quote per topic. I calibrated it against a single long summary I was happy with and told the model to match or beat that depth. Each summary costs about 13 cents, which is cheap enough that I never think about it.

Claude returns the whole thing as structured JSON, so it drops straight into the database without any parsing guesswork:

typescript
const stream = anthropic.messages.stream({
  model: "claude-opus-4-8",
  max_tokens: 32000,
  thinking: { type: "adaptive" },
  output_config: {
    effort: "high",
    format: { type: "json_schema", schema: SUMMARY_SCHEMA },
  },
  system: SYSTEM_PROMPT,
  messages: [{ role: "user", content: transcript }],
});

const message = await stream.finalMessage();

The backend: Neon, Clerk, and a background worker

The data lives in Neon, a serverless Postgres, with Drizzle as the query layer. The summary itself is stored in a JSONB column rather than flat text. Each summary is a structured object: lede, sections, quotes, takeaways. JSONB matches the shape of the model output and preserves the hierarchy that flat text would lose. It also let me keep my old summaries, in a slightly different shape, alongside the new ones. The app renders both.

Auth is handled by Clerk: sign in with Google, GitHub, or email. Anonymous visitors get the read-only showcase; signed-in users get their own library and can generate.

The piece I am happiest with is generation. Summarizing a long episode takes time, longer than a normal web request should wait. So clicking Generate does not block. It writes a placeholder row, hands the work to a QStash background queue, and returns immediately. A worker endpoint fetches the captions, runs Claude, and saves the result, then the card flips to the finished summary. There are no request timeouts, retries are automatic, and because everything is hosted, it runs with my computer switched off. A small rate limit keeps the bill predictable.

The personal tool philosophy

There is a specific kind of side project worth finishing: one you will actually use. Most side projects die halfway through because the motivation is learning or showing off, not solving a real problem you have. Those projects feel like work once the interesting parts are done.

This one is different. I use it after almost every podcast I listen to. That usage is the best forcing function for polish: you notice the rough edges because you hit them yourself. You fix the bug where the summary cuts off because you saw it happen to a podcast you cared about. You make the writing deeper because the thin version annoyed you personally. Rebuilding it around Claude came from the same instinct. The old summaries were not good enough for me, so I changed the part that mattered.

The projects I have actually finished are the ones where I was the first and most frequent user. This is the clearest example of that in my work. It was not built to impress anyone. It was built because I needed it.

Where to find it

The live app is at podcast-blog-v2.vercel.app. If you listen to a lot of podcasts and want a searchable archive of what you have covered, paste a link and see what it does.

Related posts