# LongCut turns a long video into a workspace of highlights, quotes and notes

> LongCut is a Next.js application that takes a YouTube URL and produces highlight reels, timestamped answers from a chat grounded in the transcript, memorable quotes and your own notes, with the text generation routed through interchangeable provider adapters. The engineering worth reading is in the cost controls: cached analyses, per tier rate limits, hashed identifiers for anonymous users and a spend policy for the caption vendor.

**SamuelZ12/longcut** — The best way to learn from long videos

- Repository: https://github.com/SamuelZ12/longcut
- Website: https://www.longcut.ai
- Stars: 1,195 · Forks: 214
- Language: TypeScript
- License: AGPL-3.0
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/samuelz12-longcut

## The product, and the two ways to generate

LongCut turns long form YouTube videos into a structured learning workspace: paste a URL and the app generates highlight reels, timestamped AI answers, and a place to capture your own notes, so that you can absorb an hour long video in minutes.

The feature list shows the shape of it. AI highlight reels come in two modes, Smart for quality and Fast for speed, with Play All playback and theme based re-generation, so you can ask for a different cut of the same video rather than being stuck with the first one. Alongside the reels, the app surfaces an AI powered quick preview, a structured summary, suggested questions and memorable quotes, and the documentation says they are surfaced in parallel, which is a design decision about attention rather than a technical one.

The chat is grounded in the transcript and returns structured JSON responses with timestamp citations, and it falls back when the provider rate limits, which is the difference between a demo and something you use daily. The transcript viewer stays in sync with the YouTube player, and clicking a sentence jumps the player to that point or captures the quote, so the transcript is a navigation surface rather than a wall of text.

Your own notes are the part that makes it a learning tool rather than a summary tool. There is a personal notes workspace that can take its source from the transcript, from the chat or from a takeaway, and an /all-notes dashboard that aggregates notes across videos with filtering and sorting for cross-video review. The library pages, behind authentication, hold saved analyses, favourites, generation limits and profile preferences.

The audience is anyone with a backlog of long recordings and no time, and the stack is a Next.js 15 and React 19 application with Turbopack, Tailwind CSS v4 and shadcn/ui components. The licence is AGPL-3.0, the site is longcut.ai, and the last push was on 2026-09-26 with no tagged releases.

Running it locally is three commands, and the prerequisites are a Node version, a Supabase project and two model keys:

```bash
git clone https://github.com/SamuelZ12/longcut.git
cd longcut
npm install
```

The environment file is where the configuration decisions live, and the first entries are the text provider and its model:

```bash
AI_PROVIDER=minimax
NEXT_PUBLIC_AI_PROVIDER=minimax
AI_DEFAULT_MODEL=MiniMax-M3
MINIMAX_API_KEY=your_minimax_api_key_here
```

## The provider abstraction is the core of the design

The AI pipeline is described in terms of files, and the file names tell you the shape of it.

The lib/ai-processing.ts and lib/ai-client.ts files orchestrate provider agnostic prompts, structured output schemas, fallback handling and transcript chunking, and the providers themselves live in lib/ai-providers/, which currently includes MiniMax, Grok and Gemini adapters. So the application does not call a model, it calls an adapter, and the registry in that directory is where the choice of vendor is made.

That structure is what makes the fallback behaviour possible. When a provider rate limits, the request is not lost, it is retried against the next adapter, and the same structured output schema is enforced on the way back so the UI does not have to parse prose. The environment example shows the same shape in configuration: the text generation provider is set with AI_PROVIDER and a public mirror of it, the default model is named separately, and the xAI key is described as an optional fallback text provider. The Gemini key is separate again, and the comment says plainly that Gemini remains required for the image generation route.

The transcript chunking is the part that most affects quality. A long video's transcript does not fit in a model context window, so the text is chunked, and the results are pooled, which is the candidate pooling named in the file description. The chunks are what the summary, the quotes and the suggested questions are derived from, and a chunking decision that is wrong will produce a summary that is technically about the video and practically useless.

For a user, the practical consequence is that the choice of model is a configuration change rather than a code change, and that a rate limited provider degrades into a slower answer rather than an error.

## Transcripts come from the video, and sometimes from a paid vendor

The transcript side has two paths, and one of them costs money, which is the detail that deserves attention.

The /api/transcript route extracts public YouTube captions directly, and the /api/video-info route fetches public video metadata from YouTube using the oEmbed endpoint, with a minimal fallback. So the normal case is free: the app reads the captions that YouTube already has and asks YouTube for the title and the thumbnail.

The environment example adds the complication. There is a variable for native caption vendor spend, with a comment that an empty or invalid value disables the dispatch to that vendor while cache and direct reads remain free, and a note to set a particular mode only after applying the reviewed migration. There is also a spend policy variable, and the comment documents the matrix in the form of a limit, a window and a concurrency value per tier:

```bash
# Matrix (24h / 30d / concurrent): guest 2/6/1, free 5/30/1,
# top-up or pro 25/300/2, customer-unlimited 50/600/2; global 200/5000/10.
```

That is an unusual thing to find in an example environment file, and it is a good sign about how the project is run. A transcript extraction service that is free for public captions and paid for vendor quality is exactly the kind of dependency where an unmonitored deployment turns into an invoice, and the project has written the limits down as a matrix, with the tiers matching the ones in the product, where a top-up or pro tier buys more of the same.

The consequence for a reader is that the cost of analysing a video depends on where the captions come from, so the caching behaviour in the feature list, aggressive caching of previous analyses with background refresh tasks, is not only a performance feature but a cost control.

## Supabase carries auth, data and the rate limits

Supabase provides authentication, persistence, rate limiting and profile preferences, and the architecture section says which tables hold what.

The persistence layer stores video_analyses, user_videos for history and favourites, user_notes, profiles for the topic generation mode and profile data, and rate_limits. Authentication is Supabase Auth with session refresh in middleware.ts, and an AuthModal component drives the sign-up prompts when a limit is hit, which is a nicer pattern than an error page when someone exhausts their free quota.

The rate limiting is the part with the most detail, and it appears in three places. The feature list says there are rate limits for anonymous and signed-in users, and the architecture section says the global middleware adds hashed IP identifiers for anonymous rate limiting. The application pages show the same idea at the product level, with a landing page that carries a mode selector and auth modal triggers when rate limits are reached, and a library page with generation limits shown to the user. And the environment file spells out the numbers, with a matrix of limits and windows per tier and a global cap.

The hashed IP identifiers are the detail worth pausing on. Hashing the address before it is stored means the rate limit table does not become a list of the addresses of everyone who used the site, which is both a privacy property and a data minimisation one, and the CSRF salt in the environment example is the same idea applied to the other side.

The payment side is Stripe, with a secret key, a publishable key, a webhook secret, a pro price id and a top-up price id in the environment example, and scripts in the package manifest for a smoke test, for setting up a portal and for creating prices. The top-up price is what connects the rate limit tiers to a purchase.

## The security layer is a shared wrapper, not a convention

The security posture is described in two places, and the consistent idea is that the protections are applied by construction rather than by remembering.

The feature list says there is security middleware that enforces CSP headers, CSRF protection, body size caps and Supabase backed rate limiting. The architecture section fills in the detail: global middleware adds CSP and HSTS headers, CSRF tokens for stateful requests, hashed IP identifiers for anonymous rate limiting and request body size guards, and the route handlers use a shared withSecurity middleware for CSRF, input validation with Zod and rate caps.

The API surface confirms the shape. There are dedicated security utility endpoints, a CSRF token route and the shared withSecurity middleware, which is listed as providing allowed methods, rate limits and CSRF validation. And there are separate endpoints for rate checks, so the client can ask whether it is allowed to proceed before it spends money on a generation. The notes client in lib/ is described as CSRF protected, so the protection is applied on the client side of the boundary too.

The validation side is a set of Zod schemas in a shared file, lib/validation.ts, shared across endpoints, which is the part that stops a new route from inventing its own input rules.

One more thing in the environment example is worth noting. The YouTube API key and the unlimited video users variable are separate from the model keys, and the translation selector is a public flag that defaults to false, with a Google Cloud Translate dependency in the manifest behind it. So the feature surface is opt-in where it costs money, which is the same discipline as the spend policy.

## The pages, the routes and the test setup

The application pages are a small set, and each one is a page with a clear job. The landing page has a branded URL input, a mode selector and the auth modal triggers. The primary workspace is at /analyze with the video id, and it contains the YouTube player, the highlight reels, a theme selector, and the summary, chat, transcript and notes tabs, with the suggestions and the note saving flows. The library at /my-videos requires authentication and holds the saved analyses with search, favourites and quick resume. The notes dashboard at /all-notes aggregates notes across videos with filtering, sorting, markdown rendering and deletion. And the settings page handles the name, the password, the usage stats and the preferred topic generation mode.

Underneath, the API surface is grouped by function. Video ingestion has the video info, transcript, cache check, analysis, save, update and link routes. AI generation has topics, summary, quick preview, suggested questions and top quotes. The conversational tools are the transcript grounded chat with citations and a limit check. User data is notes, all notes and toggle favourite.

The test setup is worth a look, because it is unusual. The test script runs vitest and then runs a second suite with the tsx test runner over the lib, components and app test files, so there are two test runners in play. There are also dedicated scripts for exercising the rate limiter database, the transcript spend database, the initial analysis database and the transcript cache database, each run as a node script against a real database rather than a mock. And there is a validate-env script, which is a sensible thing to run before the application starts.

The repository also carries a CLAUDE.md described as an extended architecture and contributor handbook, a .jules/ directory, and both a package-lock and a pnpm-lock, with the readme noting that the project uses npm although pnpm or yarn also work.

## Conclusion

LongCut suits a learner or a team that consumes long recorded material, such as conference talks and lecture series, and who wants to search it and annotate it rather than watch it at double speed. It is the wrong choice if you need the transcripts to be legally clean, because the caption extraction path can dispatch to a third party vendor, and a poor match if you want to self-host it without Supabase, since authentication, persistence, rate limiting and profile preferences all live there. Before running it, read the spend policy section of the environment example, because the transcription step has a per tier cost matrix, and check which provider you are pointed at, since the default model and the fallback order are configuration rather than code.

## FAQ

### What does LongCut do with a YouTube video?

It turns the video into a learning workspace with AI highlight reels in Smart or Fast modes, a quick preview, a structured summary, suggested questions, memorable quotes, a chat grounded in the transcript with timestamp citations, and a notes workspace that can draw from the transcript, the chat or a takeaway.

### Which AI providers does LongCut use and how are they configured?

Text generation is routed through provider adapters in lib/ai-providers, currently MiniMax, Grok and Gemini, with the provider and default model set through environment variables and the xAI key documented as an optional fallback. Gemini remains required for the image generation route.

### How does LongCut control its costs?

Analyses are cached aggressively with background refresh, rate limits are enforced per tier through Supabase with hashed IP identifiers for anonymous users, and the environment example documents a spend policy matrix for the native caption vendor, with cache and direct caption reads remaining free.

### What do I need to run LongCut locally?

Node.js 18 or newer, with 18.18 or later for Next.js 15, npm although pnpm or yarn also work, a Supabase project for Auth and Postgres, a MiniMax API key for text generation, and a Gemini API key if you want image generation. Clone the repository, run npm install, and copy the environment example to .env.local.

## Sources

- [Issues](https://github.com/SamuelZ12/longcut/issues)
- [License: AGPL-3.0](https://github.com/SamuelZ12/longcut/blob/main/LICENSE)
- [Project website](https://www.longcut.ai)
- [README](https://github.com/SamuelZ12/longcut/blob/main/README.md)
- [SamuelZ12/longcut on GitHub](https://github.com/SamuelZ12/longcut)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/samuelz12-longcut
