How I Built RuntimeWire: A One-Person, Mostly-Autonomous AI Newsroom | by Ryan Merket | May, 2026 | MediumSitemapOpen in appSign up<br>Sign in
Medium Logo
Get app<br>Write
Search
Sign up<br>Sign in
How I Built RuntimeWire: A One-Person, Mostly-Autonomous AI Newsroom
Ryan Merket
10 min read·<br>Just now
Listen
Share
There’s a particular kind of madness that sets in when you decide to build a newsroom by yourself. Not a blog. A newsroom — something that wakes up before you do, reads the entire startup and AI firehose, decides what matters, writes it up, makes a video about it, narrates that video, posts it to YouTube and X, drops an episode into a podcast feed, and emails a recap to subscribers. All before you’ve had coffee.<br>That’s RuntimeWire. It’s a real-time tech publication covering startups, funding, and AI — and it’s run entirely by one person and a few thousand lines of TypeScript.<br>This post is the “how.” If you’re a solo builder, a hacker, a dreamer, or an investor who likes watching the sausage get made, pull up a chair. I’m going to show you the actual machine.<br>The bet<br>The bet behind RuntimeWire is simple: a single person with the right automation can out-publish a newsroom . Not out-report — the deep, source-driven, call-fifteen-people scoops still belong to humans. But the relentless, around-the-clock job of surfacing what’s happening and packaging it for every channel? That’s an engineering problem. And engineering problems are the kind I like.<br>Press enter or click to view image in full size
homepage screenshot / runtimewire.comSo I built the publication I wished existed, then I automated myself out of as much of it as I could.<br>The stack<br>I kept it boring on purpose. Boring scales; clever breaks at 3am.<br>Monorepo : pnpm workspaces. One repo, multiple deployable artifacts (the API, the website, internal tooling) plus shared libraries.<br>Language : TypeScript 5.9 on Node 24, strict everywhere.<br>API: Express 5. Yes, Express. It’s 2026 and it still just works.<br>Database : PostgreSQL with Drizzle ORM. Type-safe queries, real migrations, no surprises.<br>Validation : Zod end to end. Every input and output the server touches is schema-checked.<br>Contract -first APIs : I write an OpenAPI spec, then generate the React Query hooks and Zod schemas from it with Orval. The frontend and backend can never silently disagree about a shape, because they’re both generated from the same source of truth.<br>Frontend : Vite + a tiny router (wouter). No framework-of-the-month. Fast builds, fast loads.<br>Build : esbuild bundles the server into a single CJS file. Cold starts are measured in milliseconds.<br>None of this is exotic. The leverage isn’t in the tools. It’s in what I wired them up to do.<br>The pipeline: ingest → curate → publish<br>The heart of RuntimeWire is a pipeline that runs continuously. At the surface it’s three steps:<br>Ingest. A poller pulls in stories from across the tech world around the<br>clock. Everything lands in a staging table as raw, unpublished candidates.<br>Curate. Models triage the firehose — classifying, deduping, and scoring<br>what’s actually a story versus noise. A scoop about a Series A gets flagged differently than a rehash of yesterday’s press release.<br>Publish. Approved stories get written up, slugged, given hero treatment,<br>tagged, linked to the companies and people involved, and pushed live —<br>either immediately or on a scheduled publish queue.<br>But "curate" and "publish" are doing a lot of hidden work in that list. The real structure is a newsroom: an assignment editor, a reporter, and a copy desk— except all three are agents with very specific jobs and very different temperaments. This is the part people ask about, so let me open it up.<br>Step 1, for real: ingest<br>A poller wakes up every 30 seconds and asks one question: which sources are due for a fetch? Sources are RSS feeds, scraped pages, X Lists, and Threads. To keep multiple ticks from stepping on each other, claiming a source is atomic — one worker grabs it, everyone else moves on.<br>The X ingestion has a wrinkle I'm weirdly proud of. A single tweet is almost never the story; the thread is. So instead of grabbing the root post and calling it a day, the ingester pulls the author's full thread — up to ~50 posts — so the system captures the actual context a founder laid out, not just the hook. Everything lands in an 'ingested_stories' table marked 'new' and 'pending', with a quick regex-based first guess at the category (funding, products, founder-moves, and so on). That first guess is cheap and disposable — the real judgment comes next.<br>Step 2, for real: the assignment editor<br>This is where most of the "is this even a story? " intelligence lives, and it's the agent I tuned the hardest.<br>Every curator tick pulls up to 25 candidates — the 'new' and freshly enriched ones — and ages out anything older than ~48 hours, because stale news isn't news. Those candidates go to a model (a smaller, fast one — 'gpt-5-mini' in the current config) running under a system prompt I...