How to Build Karpathy's HackerTube with Claude Code or Codex: Mine Hacker News Comments for a Video Site Without an Algorithm (Tested)

Karpathy built HackerTube in about two hours with Claude Code and Opus 5.5, picking 6,454 YouTube videos that Hacker News commenters kept recommending over 20 years. We had Claude Code and Codex each build a mini version with our API key: fetch two months of comments from the official HN Algolia API, extract YouTube links, count and dedupe them, and generate a static page. Includes the full prompt, run times, a side-by-side comparison and the steps between the mini version and HackerTube.

11 分钟阅读
How to Build Karpathy's HackerTube with Claude Code or Codex: Mine Hacker News Comments for a Video Site Without an Algorithm (Tested)

Short answer: the idea behind HackerTube is simple. Find every YouTube link ever posted in a Hacker News comment, keep only the videos that many different people recommended across many different months, and turn them into a video site with no login and no recommendation algorithm. With Claude Code or Codex, one prompt is enough to build a working mini version.

  • According to Karpathy's original post (November 1, UTC), he was annoyed with YouTube's recommendations, so he had Claude filter about 43M comments from 20 years of HN down to 6,454 videos that keep being recommended. It took about two hours with the Claude Code desktop app and Opus 5.5 on Medium effort. His only manual work: creating a Google Cloud API key to query YouTube metadata, starting a VPS and buying the domain. As of the afternoon of November 2 (UTC+8), the post had about 3.3M views, 39.7K likes and 34K bookmarks.
  • We had Claude Code and Codex each build a mini version with our API key, using the official HN Algolia API for September and October 2026. Both finished in about 9 minutes, both found about 3,600 comments with YouTube links and more than 3,500 distinct videos, both kept 193 videos linked by at least 2 different people, and the top 3 were identical.
  • The gap between the mini version and HackerTube is judging whether a comment actually recommends the video. Ranking by link counts alone pushes news-of-the-week videos to the top: all 12 mentions of the number 3 video came from a single thread. The prompt for that missing step is near the end.

Create an API Key and build your own HackerTube in Claude Code, Codex or Cursor →

What HackerTube is and how Karpathy built it

HackerTube describes itself as "the YouTube videos that Hacker News keeps telling each other to watch". According to its about page, it currently lists 6,454 videos, based on 39,834 HN comments that mention them, sorted into 150 topics in 16 areas and spanning 2007 to 2026. Likes, history and Watch later live only in your own browser, there are no accounts, and thumbnails are a frame from the middle of the video instead of the uploader's optimized cover.

According to the "How it was built" section of the about page, it works in five steps:

StepWhat HackerTube does
1. Read every commentScan a public archive of all of HN (the open-index/hacker-news dataset) for YouTube links, which turns up well over a hundred thousand videos
2. Keep the repeat picksAt least 3 different people linked it with real commentary, in at least 3 different months; about 7,000 videos remain
3. Read each comment with a modelClaude reads the comment with its story title and decides whether it recommends, cites, jokes about or criticizes the video, and picks a quote and topics
4. Write a card per videoFrom YouTube details and everything HN said: a summary, why HN likes it, the type, and whether it has aged well
5. RankBy the number of distinct months people recommended it in; being linked again over the years beats one viral spike

The about page also says the whole site, data pipeline, search and recommendations were built by Claude Opus 5.5 in Claude Code, and that the comment labels and video cards were written by Claude Sonnet 5.5 agents coordinated by Opus. The data is published too: the Data page offers a zip of about 17.8 MB with videos.jsonl, mentions.jsonl, the topic list, embeddings and a DATA.md written for agents, under ODC-By 1.0. Karpathy's suggestion in the post is to point your Claude at it and ask for your own version.

According to X trend summaries (one, two), people have already built follow-ups such as Hacker Papers for arXiv and lists of books and blogs.

What the mini version does

Rebuilding 20 years of data means downloading the full HN archive, which is too much for a first try. We narrowed it to two months and used only the official HN Algolia search API, which needs no key:

StepHowOutput
1. Fetch commentsAlgolia search_by_date, tags=comment, split into time windowsdata/comments.jsonl
2. Extract linksPull 11-character video ids from the comment text, covering watch?v=, youtu.be/, /shorts/ and othersVideos mentioned in each comment
3. Count and dedupeMentions, distinct people and distinct months per videoRanking
4. Add titlesYouTube oEmbed, no key neededdata/videos.json
5. Build the pageOne static HTML file with a card grid and a client-side search boxsite/index.html

Step 1: Create an API Key and connect Claude Code or Codex

  1. Sign up at aicodewith.ai, log in, open Key management, create a key and copy the full string.
  2. Claude Code: set the base URL and key, create an empty folder and start it there:
bash
export ANTHROPIC_BASE_URL="https://api.aicodewith.ai"
export ANTHROPIC_AUTH_TOKEN="YOUR_API_KEY"
mkdir -p ~/hackertube-mini && cd ~/hackertube-mini
claude --model claude-opus-5-5

To save the settings permanently or set them up on Windows, see How to connect Claude Code to a third-party API. Karpathy used Opus 5.5 on Medium effort; for choosing a level see Claude Opus 5.5 effort levels, and for a model comparison see Which model to use in Claude Code.

  1. Codex: put the following in ~/.codex/config.toml, with the key written directly in experimental_bearer_token:
toml
# ~/.codex/config.toml
model = "gpt-6.1-sol"
model_reasoning_effort = "medium"
model_provider = "aicodewith"

[model_providers.aicodewith]
name = "aicodewith"
base_url = "https://api.aicodewith.ai/chatgpt/v1"
wire_api = "responses"
experimental_bearer_token = "YOUR_API_KEY"

Every field is explained in Codex config.toml explained. If you are new to Codex, start with How to use Codex and How to install Codex.

Step 2: Look at the HN Algolia API yourself first

Run one request before you start so you know what the data looks like. This one asks for comments posted on 2026-09-01 that contain youtu (it matches both youtube.com and youtu.be):

bash
# comments posted on 2026-09-01 (UTC) that contain "youtu"
curl "https://hn.algolia.com/api/v1/search_by_date?query=youtu&tags=comment&hitsPerPage=1000&numericFilters=created_at_i>=1788220800,created_at_i<1788307200"

In our test, HN had 10,830 comments that day and 197 of them contained youtu. Two limits matter:

  • Each query returns at most 1000 hits. Over two months, youtube.com alone matches more than 4,000 comments and the rest are cut off, so the time range has to be split into small windows.
  • Searching for youtube misses short links. youtu.be/xxxx doesn't contain the word youtube. Search for the youtu prefix and match exactly with a regex locally.

We put both points in the prompt, and both Claude Code and Codex still tested the requests and confirmed the limit before writing the pipeline.

Step 3: Give the prompt to the agent

Save the text below as prompt.txt and give it to Claude Code or Codex. This is exactly what we used:

text
Build a mini "HackerTube" in this folder: a static site of the YouTube videos that Hacker News commenters keep recommending to each other.
1. Fetch data only from the official HN Algolia API (https://hn.algolia.com/api/v1/search_by_date, tags=comment). Take every comment created from 2026-09-01 00:00 UTC to 2026-10-31 23:59 UTC that contains a YouTube link (youtube.com/watch, youtu.be/, /embed/, /shorts/, m.youtube.com, music.youtube.com). Note the API returns at most 1000 hits per query, so split the time range into small enough windows. Be polite: at most 2 requests per second. Save raw hits to data/comments.jsonl.
2. Extract and normalize the 11-character video ids (HTML-unescape the comment text first), and drop the commenter's own repeated links within the same comment.
3. For each video count: mentions, distinct commenters, distinct months, first and last mention, and keep up to 3 short quotes with links to the HN comment (https://news.ycombinator.com/item?id=...). Keep a video only if at least 2 different people linked it. Rank by distinct commenters, then mentions.
4. Get titles for the kept videos from YouTube oEmbed (https://www.youtube.com/oembed?url=...&format=json, no API key); if oEmbed fails keep the id and mark it unavailable. Save data/videos.json.
5. Generate site/index.html: a single static page, no login and no tracking, with a grid of cards (thumbnail from https://i.ytimg.com/vi/<id>/hqdefault.jpg, title, channel, "N people / M mentions", one quote) and a client-side text filter.
6. Write the whole pipeline as a reusable script build.py (stdlib only, with a --since/--until option) and run it. Finally reply with: total comments fetched, unique videos found, videos kept, the top 10 videos (id, title, people, mentions), and any problems you hit.

Three things in this prompt matter: naming the official API as the only data source keeps the agent from scraping web pages; stating the 1000-hit limit and the request rate up front keeps it from discovering missing data halfway through; and asking for a rerunnable build.py means a new time range or threshold doesn't need a new conversation.

To run it in the background, use non-interactive mode. Claude Code's --allowedTools allows only the commands this job needs. Codex's default sandbox has no network access, so we used --sandbox danger-full-access in a dedicated empty folder; that permission is broad, so don't use it in a folder with important files. See Codex automation permissions for the options:

bash
# Claude Code, non-interactive: only allow the commands this job needs
cat prompt.txt | claude -p --model claude-opus-5-5 \
  --permission-mode acceptEdits \
  --allowedTools "Bash(python3:*)" "Bash(curl:*)" "Bash(ls:*)" "Bash(mkdir:*)" "Bash(head:*)" "Bash(wc:*)"

# Codex, non-interactive (reads the prompt from stdin)
codex exec --skip-git-repo-check --sandbox danger-full-access - < prompt.txt

Test: Claude Code and Codex with our API key

Both clients got the same prompt and ran at the same time on the same Linux machine on the afternoon of November 2, 2026:

Claude Code 2.1.316 + Opus 5.5Codex 0.166.0 + GPT-6.1 Sol
TimeAbout 555 seconds, 21 turnsAbout 534 seconds, 30 commands run
How it fetchedDaily windows searching youtu, splitting any window over 1000 hits in half; 61 requests61 daily windows searching youtu, checking that none reached 1000
Comments with YouTube links3,6243,619
Distinct videos3,5113,505
Kept (2 or more people)193193
No title found2 (oEmbed returned 403 and 401)Same
Self-checksCompared against a full scan of one day; both found the same 87 comments with linksWrote 5 tests and opened the page in headless Chrome to check the cards and the search box
Outputbuild.py 418 lines, index.html about 258 KBbuild.py 258 lines, index.html about 210 KB

Both clients chose the same approach on their own: instead of scanning every comment (about 600,000 in two months), they searched each day for youtu and matched exactly locally. Claude Code also verified that shortcut: a full scan of September 1 gave exactly the same result as the prefilter, and it noted that searching for youtube would have missed 20 comments with short links.

The top 10 was almost the same on both sides and the top 3 were identical. We also counted how many mentions of each video came from a single thread:

RankVideoPeopleMentionsMonthsMost in one thread
1216,000,000 Spy TVs – The LG Smart TV Problem151827
2Kernel Recipes 2026 - Security in the LLM age122112
3The FLYING Tesla Roadster explained by the man who engineered it1112112
4LG Says We're Fake News6716
5Reinventing Entropy – Compression is Intelligence Part 16623

Each video in data/videos.json looks like this, with quotes linking back to the original HN comment:

json
{
  "id": "6IFVTcM28KA",
  "title": "216,000,000 Spy TVs | The LG Smart TV Problem",
  "people": 15, "mentions": 18, "months": 2,
  "first_mention": "2026-09-07T10:52:26Z",
  "last_mention": "2026-10-13T16:41:11Z",
  "quotes": [
    {"author": "wavesplash", "date": "2026-09-07",
     "url": "https://news.ycombinator.com/item?id=49597752",
     "text": "... Worth a watch to see how bad this is"}
  ]
}

The generated build.py can be rerun with a different time range or threshold (Claude Code's version shown):

bash
python3 build.py --since 2026-09-01 --until 2026-10-31   # full run
python3 build.py --skip-fetch --min-people 3              # rebuild from saved comments with a stricter rule
python3 build.py --full-scan                              # scan every comment instead of the "youtu" prefilter (slow)

Three problems the test turned up

  1. Ranking by link counts treats news of the week as a classic. All 12 mentions of the number 3 video came from one thread discussing that video, and 6 mentions of the number 4 video came from one thread too. That is exactly why HackerTube requires at least 3 different months and has a model judge each comment. In our two months of data, only 22 videos had at least 3 people and at least 2 months.
  2. People often paste broken URLs, and the two clients handled them differently. Claude Code kept 5 more comments than Codex, all with URLs like the ones below. Claude Code took the first 11 characters and kept them; Codex parsed them as standard URLs and dropped them. The third one actually has two extra characters, so taking the first 11 may point to the wrong video:
text
https://www.youtube.com/watch?v=sCr_gb8rdEI?t=11m     <- "?" instead of "&"
https://youtu.be/69o-8Mtd3Kc&t=330                    <- "&" instead of "?"
https://www.youtube.com/watch?v=909o_kbCdFgll         <- 13 characters, not 11
  1. oEmbed doesn't return a title for every video. 2 of the 193 kept videos returned 403 or 401, most likely private or with embedding disabled; both clients marked them unavailable and showed only the id. For duration, view counts and similar details you need a YouTube Data API key from Google Cloud, as Karpathy did.

From the mini version to HackerTube

First, have a model judge each comment. This makes the biggest difference. In the mini version's folder, tell the agent:

text
For each comment in data/comments.jsonl, read the comment text and the HN story title,
and label what the commenter does with the video: strong_rec, rec, reference, joke or critical.
Write the labels to data/stance.jsonl. Then only count strong_rec and rec,
keep a video if at least 3 different people recommended it in at least 3 different months,
and rank by the number of distinct months. Rebuild site/index.html.

Judging thousands of comments one by one is slow, so let the agent split them into parallel batches. Running too many Codex tasks at once can hit 429 errors; see How to fix Codex 429 Too Many Requests for controlling concurrency.

Second, use more data. Algolia is good for fetching by time range; to cover 2007 to today, the open-index/hacker-news archive mentioned on HackerTube's about page is a better fit. The easiest route is to download HackerTube's data zip, have the agent read DATA.md first, and then change the interface or ranking to your taste.

Third, deploy it. The mini version is a static page that opens on any static host. According to Karpathy's post, he gave Claude the VPS IP and told it to update, secure, harden, deploy and optimize, and Claude did the whole thing.

Common questions

Algolia returns fewer hits than nbHits

Each query returns at most 1000 hits; nbHits is only the total. Make the time windows smaller until every window has fewer than 1000 hits. Daily windows were enough for us, and busy days can be split in half again.

Why searching for youtube misses links

Short youtu.be links don't contain youtube. Search for youtu, then filter locally with a regex for watch?v=, youtu.be/, /embed/, /shorts/ and similar forms.

Links in comments look like &#x2F;

Algolia returns comment_text HTML-escaped: / becomes &#x2F; and & becomes &amp;. Unescape the HTML before extracting links or the regex won't match anything. Item 2 of our prompt says this explicitly.

Doing the same for papers, books or podcasts

Replace YouTube in the prompt with arxiv.org/abs/, amazon.com/dp/ or podcast links; the counting and page logic can stay the same. For reading papers afterwards, see Search and read arXiv papers with Claude Code.

Making the agent follow the same rules every time

Put the data source, thresholds and page requirements in the project's CLAUDE.md or AGENTS.md; see How to write CLAUDE.md for Claude Code.

Summary

HackerTube shows that small products that "filter content by other people's taste" are now a one-person job with a coding agent. In our test, scraping Hacker News comments with Claude Code or Codex, extracting YouTube links and producing a usable static video site took about 9 minutes. What really decides the quality is the rule for what counts as a recommendation, and whether the time span is long enough.

Create an API Key and start building in Claude Code, Codex or Cursor →

相关文章

How to Use DeepSeek Harness Creator Mode: Install, Connect a Third-Party API and Build Your First Plugin

How to Use DeepSeek Harness Creator Mode: Install, Connect a Third-Party API and Build Your First Plugin

On November 2 the official DeepSeek Harness account showed off Creator Mode, where you describe a tool in one sentence and the agent writes the plugin, installs it into Harness and checks that it loaded. This guide explains what Creator Mode is, how to start Harness with npx, how to connect an OpenAI-compatible third-party API (aicodewith base URL + key) to use Claude, GPT and DeepSeek models, and walks through building a todo_scan plugin with Creator Mode, with real outputs, common errors and the Claude Code / Codex equivalents.

Claude Code auto mode failing every turn behind a gateway? 2.1.317 fixes gateway 403/422 (upgrade + tests)

Claude Code auto mode failing every turn behind a gateway? 2.1.317 fixes gateway 403/422 (upgrade + tests)

Claude Code 2.1.317 (released November 3) fixes auto mode failing every turn when ANTHROPIC_BASE_URL points at an LLM gateway that answers 403 or 422 to the server-side safety check. This guide covers what changed, which third-party gateway and relay users are affected, how to upgrade and check the version, how to set the Base URL and key and turn on auto mode, plus side-by-side tests of 2.1.316 and 2.1.317, an error table and FAQ.

How to Use Claude Message Threads: Messages API Threads Beta, Send Only New Messages, ~35% Faster First Token (Claude Code / API Tested)

How to Use Claude Message Threads: Messages API Threads Beta, Send Only New Messages, ~35% Faster First Token (Claude Code / API Tested)

On November 2, Anthropic put Message Threads into public beta on the Messages API. The first request sends the full conversation and creates a thread; after that each turn sends only the new messages and the id of the previous response. Long conversations get a faster first token, while token usage and billing stay the same. This guide explains the thread parameter, the beta header, the 5-minute expiry and the 404 replay from the official docs, gives curl, Python and TypeScript examples, and reports our test with an aicodewith key: through aicodewith the thread field is currently ignored and continue turns lose earlier context, Claude Code is not affected, plus the workaround and common errors.