heading · body

YouTube

Jon Gjengset on Rust Internals, Vibe Coding, and Teaching by Streaming

Rock the JVM published 2026-04-01 added 2026-04-11 score 7/10
rust programming-languages llm ai-coding vibe-coding borrow-checker type-systems software-engineering teaching code-comments unsafe concurrency
watch on youtube → view transcript

Jon Gjengset on Rust Internals, Vibe Coding, and Teaching by Streaming

ELI5/TLDR

A long, careful conversation with Jon Gjengset — author of Rust for Rustaceans and one of the most respected Rust educators on YouTube — about three things: what AI coding assistants are actually good and bad at, why Rust feels mean to newcomers and what it’s secretly trying to teach them, and a small confession that he writes his code comments in bright orange because he thinks comments matter more than the code itself. The throughline is taste — how an experienced programmer develops intuition about which tools to trust, which fights to pick, and where to put the thinking that doesn’t fit inside the code.

The Full Story

Vibe Coding in Rust: Easier, Harder, Safer, More Dangerous

The interviewer asks the obvious opening question — is letting an AI write Rust safer than letting it write Python, given Rust’s strict compiler? Gjengset’s answer is that it is simultaneously all four things. (Quick translation for anyone not in this world: “vibe coding” is the new term for letting an LLM write most of your code while you supervise loosely; the borrow checker is Rust’s compile-time bouncer that refuses to let your program compile if two parts of the code might touch the same memory in unsafe ways.)

It’s harder because the borrow checker rejects a lot of plausible-looking code an LLM would happily generate. It’s safer because that rejection acts as a filter — bugs that compile have to be a different, narrower class of bug. It’s more dangerous because programmers start trusting the compiler too much. “It compiles, so it must be correct” is only true if you chose your types so carefully that compiling actually proves something — and an LLM almost never does that. And it’s easier because in a strongly-typed language the LLM can lean on the compiler the same way a human does: make a refactor, watch the compiler complain, follow the breadcrumbs.

“The Rust compiler team has put a lot of work into making the Rust compiler give you really good error messages and warnings. And those are useful not just to humans, but also to the LLMs observing it.”

This is one of those moments where you realize a feature built for one audience (frustrated humans) accidentally became infrastructure for another (machine readers).

Two Weeks of Forced Use

After his first agentic-coding livestream, Gjengset spent two weeks doing absolutely nothing without an LLM. The point wasn’t to find out whether they were good — it was to map what he calls the “convex hull” of their usefulness. Where do they save time? Where do they waste it? Where are you surprised? His advice for anyone trying to develop the same intuition is the same: force yourself to use it for everything for two weeks, including the cases where you’re sure it’s pointless. Your prior beliefs about what it would be good and bad at will be partly right and partly wrong, and the partly-wrong cases are the entire point of the exercise.

He distinguishes two ways an LLM can help. The first is time savings — it just does the task faster than you would. The second is parallelism — you would do it faster yourself, but if the LLM can chug along quietly in the background while requiring almost no cognitive supervision, you can do another task at the same time. He compares this to IO parallelism in computing: a slow background job that occasionally needs an input, leaving your main thread free for the work that actually needs your brain.

The sweet spot for delegating to an LLM, in his experience, is when you have something close to an oracle — a perfect specification of what correct output looks like, ideally as a thorough test suite. The LLM does a “semi-random walk” through possible solutions and bounces off the test wall until something sticks. Where it breaks down is when the work requires genuine algorithmic insight (it won’t invent a smarter algorithm for you) or when it involves an API or library it has never seen examples of. He gives a great example: a plugin for a livestream-control app called Touch Portal. The YouTube API side was trivial — millions of code examples in the training set. The Touch Portal SDK side was painful — almost no public code exists. The glue between them was fine again, because both ends were now well-defined.

The Fork in the Road

The interviewer pivots to Rust itself and asks how a newcomer learns idiomatic Rust rather than writing Java-with-Rust-syntax. Gjengset’s answer is that Rust has a built-in trick: it just won’t let you do it the wrong way. Try to port a Java mental model and the borrow checker eventually corners you. You start cloning everything, wrapping everything in Arc and Mutex (think of these as “shared pointer” and “lock around shared data”), and then you start getting deadlocks because two locks are taken in the wrong order. Suddenly the language feels like it hates your architecture.

This is the fork in the road. One path: declare Rust a bad language and quit. The other path: assume the language is trying to teach you something, and slowly rewrite your code so the friction goes away. The first time you do this it is genuinely painful — you have to learn new concepts (lifetimes, borrows, the send/sync traits — Rust’s way of marking which types are safe to move or share between threads) and rewrite a lot of what you wrote. But the lesson sticks. Next time you write code, you do the massaging proactively rather than reactively.

His honest philosophical caveat: not every language that “tries to teach you things” is actually smart. Perl, Nix, and Vimscript all force you to learn a lot, and most of it is just because they’re annoying. He thinks Rust is different because the resulting programs really are better-architected — more modular, easier to refactor, more performant — and because the borrow checker becomes a permanent resident in his head that improves his code in other languages. He says he writes better JavaScript now because some quiet voice asks how the compiler is supposed to free this memory, even though JavaScript doesn’t care.

“It’s not just like it forces you to not do things your way, but the way it pushes you is often better. Not always, but often.”

Why Rust Doesn’t Want Your Objects

A particularly nice digression on why Rust uses Haskell-style type classes (called “traits”) rather than Java-style classes. The reason isn’t aesthetic — it’s the borrow checker. If you cram all your state into one big object the way object-oriented programming wants you to, the borrow checker keeps barking at you, because Rust’s current rules say a method call that takes mutable access to self is borrowing the entire struct. Two methods that touch unrelated fields still can’t run concurrently, because the compiler only sees that both want exclusive access to the same instance.

The deeper message the compiler is trying to send: those fields probably shouldn’t be in the same object in the first place. Group state by what gets accessed together, not by what conceptually belongs to the same noun. This is one of those quiet design decisions that ends up reorganizing how you think about every program you write, regardless of language.

He also touches on unsafe — Rust’s escape hatch — and is very careful about what it actually means.

“Unsafe does not mean let me do whatever I want. Unsafe means I solemnly swear, dear compiler, that I have checked this code and it follows all your rules.”

His unsafe hygiene: keep unsafe code encapsulated (ideally in its own crate with a fully safe public API, the way the standard library wraps things like Mutex and HashMap), require a comment above every unsafe block proving you’ve checked the preconditions, and run your test suite through MIRI — an interpreter that watches every memory operation and screams if anything is undefined. For concurrent code, also run it through Loom, which exhaustively explores every possible interleaving of threads.

Rust’s Deliberate Omissions

The Rust standard library is famously narrow but deep. No regular expressions, no randomness, no concurrent hashmap, no HTTP server, no cryptography. The reasoning is partly a lesson learned from Python, where parts of the standard library have ossified — the API isn’t quite right anymore but it can’t be changed without breaking everyone, and you can’t make it the best implementation because the API isn’t right. Rust looked at this and decided to keep the standard library small and let the ecosystem evolve.

Bigger things Rust deliberately does not have: a runtime (which means no built-in async runtime, no green threads, no garbage collector), and runtime reflection (the Java thing where you can ask an object at runtime what its type is and what fields it has). Rust types are a compile-time concept. The trade-off is intentional — predictability, no surprise GC pauses, full control over what your binary actually does. The cost is ergonomics in domains where a runtime would be nice.

Comments as the Real Code

The conversation drifts into how Gjengset teaches and writes, and lands on a small confession that is probably the most interesting thing he says in two and a half hours. His syntax highlighter colors comments bright orange. Most editors use gray to fade them into the background. He inverts that on purpose, for two reasons: it forces him to read them, and it forces him to make every comment worth reading because he’ll be staring at it constantly.

“Comments are more important than the code.”

His view is that most programmers are taught to write bad comments and have very few resources for writing good ones. Code stands on its own — it doesn’t need a comment that says what the code does. What it needs is the connective tissue between lines: the why, the constraints, the things that could break, the things that should be there but aren’t yet and the reason. These are the insights you had while writing the code that would otherwise evaporate in two weeks. He quotes one of his own PhD-era comments — a 200-line block, three or four paragraphs of prose, ending in a TODO — that explains a feature the code doesn’t support and why it can’t right now. There is, he points out, nowhere else for that thought to go. Architectural decision records and RFCs live in separate documents and aren’t tied to any specific line.

His method: write the function signature first, then write a long comment inside the empty function describing what it should do, what invariants it must hold, what it probably needs to check. Then start replacing parts of the comment with actual code. The bits of comment that are left over become the explanation of the glue.

Stuck on Stream

Asked how he keeps audiences engaged during 10-hour streams when he gets stuck on a problem for two hours, his answer reframes the question. The audience isn’t bored when he’s stuck. The audience is there for the moment when he’s stuck. The journey of getting unstuck — pulling out GDB, adding print statements, writing a Perl script to grep through the log, hitting the wall and trying something else — is the actual content. The destination is incidental.

“Even if that takes me two hours, those are interesting two hours because all the things that I do to try to get myself unstuck are themselves tools that the audience can learn from.”

Closing

He ends by recommending a few books — The Art of Unix Programming, The Pragmatic Programmer, Seven Languages in Seven Weeks, The Design and Implementation of the FreeBSD Operating System, and Edward Tufte’s The Visual Display of Quantitative Information. The Tufte recommendation is the surprising one: he says programmers spend a lot of time staring at logs and tables when they should be plotting things, and most of them choose terrible visualizations because nobody taught them any better. And on his way out, his pitch to Scala developers: spend a few weeks with Rust as exposure therapy, even if you never ship it to production. The borrow checker will move into your head and quietly make you better at the language you actually use.

Claude’s Take

This is a high-quality conversation but a low-stakes one. Gjengset is one of the genuinely thoughtful voices in the Rust community — he wrote Rust for Rustaceans, he has put thousands of hours into teaching Rust on YouTube, and when he says something about borrow checker internals or unsafe hygiene he is on very solid ground. There is essentially no BS to flag in the technical Rust content. The advice on encapsulating unsafe code, using MIRI and Loom, requiring safety comments — that is just consensus best practice in the Rust community, accurately reported by someone who actually lives by it.

The LLM-coding portion is more interesting because it’s more contestable, and Gjengset is appropriately humble about it. His “two weeks of forced use” prescription is, I think, genuinely correct — most programmers’ opinions about LLMs are based on a tiny sample of cases where their priors were already correct. His framing of LLM utility along the oracle-strength axis (the better your test suite, the more autonomously the model can grind) matches what most experienced practitioners I trust report. It’s not novel — variations of this have been written about for two years now — but it’s a clean version of the conventional wisdom. The “IO parallelism” framing for using LLMs as background processes while you do compute-heavy work yourself is a useful mental model that I haven’t seen articulated quite this cleanly before.

His “comments more important than code” stance is the most distinctive thing in the interview and also the most defensible. It’s not original — literate programming goes back to Knuth — but the bright-orange-syntax-highlighting commitment device is a nice operationalization of a belief most programmers nominally agree with and never act on. The specific example of writing a long prose draft inside an empty function and then progressively replacing the prose with code is genuinely useful and I’d bet money it generalizes to non-Rust contexts.

The weakest moment is probably the “is Rust a good first language” question, where his answer is essentially “yes if you’re going to do the kind of programming where Rust’s lessons apply, otherwise no” — which is true but doesn’t really commit to anything. He also waves at Polonius (the next-generation borrow checker) without being able to give a timeline, which is fine because nobody can.

The conversation never quite breaks new ground but it never fakes depth either, which is rarer than it should be. Gjengset talks about the things he actually knows from doing them. The interviewer is competent, asks reasonable follow-ups, and stays out of the way. If you already write Rust this is a pleasant 2.5 hours of a smart practitioner thinking out loud. If you don’t, the parts about LLM intuition and comment philosophy are the parts that travel.

claude_score: 7. Good, not great. Rock-solid technical content, no unsupported claims, some genuinely useful frameworks (the two-week immersion, the oracle-strength axis, the orange-comments commitment device), but ultimately a conversation between two experienced people that confirms more than it challenges. It would be an 8 if there were more friction or more genuinely novel claims, and a 6 if Gjengset weren’t so unusually careful about distinguishing where he’s confident from where he’s guessing.

Further Reading

  • Rust for Rustaceans / Jon Gjengset / Idiomatic intermediate Rust — His own book, deliberately dense, intended to be read paragraph-by-paragraph rather than skimmed.
  • The Art of Unix Programming / Eric S. Raymond / How to decompose programs Unix-style — Short, focused on composability and the philosophy of small tools that combine well.
  • The Pragmatic Programmer / Hunt and Thomas / General craft principles — The book most senior programmers recommend when asked this question, for good reason.
  • Seven Languages in Seven Weeks / Bruce Tate / Programming language diversity — Walks through seven languages with very different paradigms, useful for breaking out of one-language-shaped thinking.
  • The Design and Implementation of the FreeBSD Operating System / McKusick et al. / How an OS kernel actually works — Deep dive into virtual memory, IO, scheduling. Slightly dated but the concepts transfer to Linux.
  • The Visual Display of Quantitative Information / Edward Tufte / How to plot data so humans can see patterns — Gjengset’s surprising pick. Argues that programmers debug performance and behavior problems badly because they look at tables instead of plots.
  • MIRI / Rust project / Memory-safety interpreter for Rust — The tool he uses to verify unsafe code; runs your tests through an interpreter that flags any undefined behavior.
  • Loom / tokio-rs / Concurrency model checker for Rust — Exhaustively explores possible thread interleavings to catch data races and deadlocks in concurrent code.