AI Engineer

Why Rust is the Ideal Language for Vibe-Coding — Daniel Szoke, Sentry

1006 summary words 4 min summary Watch video

Start with the signal

4 min read

Summary

30-second take

Daniel Szoke argues that Rust is actually better for AI-assisted coding than Python/TypeScript—not despite being harder for LLMs to write, but because of it. His core thesis: LLMs are non-deterministic "alien intelligence" that will always make mistakes, so optimizing for "easy first-pass generation" in permissive languages creates production bugs. Rust's strict compiler catches entire bug classes (memory safety, concurrency, null safety) deterministically before runtime, turning every compile error into an avoided production bug. AI agents thrive in compile-fix loops; Rust's detailed error messages guide them to correct code faster than code review agents can find subtle TypeScript bugs. Unconventional take that reframes the language choice question from "what's easiest for the model" to "what prevents AI mistakes most reliably."

Key takes

  • Python/TypeScript popularity is a false optimization: Conventional wisdom favors these for AI coding because LLMs write them easily on first try—but their flexibility is precisely what enables subtle, hard-to-catch bugs. Optimizing for "easy to generate" doesn't mean "safe to run."
  • LLMs are "alien intelligence" with unknowable failure modes: Citing Harari's Nexus, Szoke argues LLMs think fundamentally differently (token prediction vs. human reasoning), so their bugs will be unexpected—sensible-looking code with heuristic logic errors or subtle flaws humans wouldn't make. Tests and review agents can't catch everything because LLMs write those too.
  • Rust's compiler errors are deterministic guardrails better than tests: Compile-time enforcement of memory safety, strict types, null safety, and thread safety catches entire bug classes that tests only probabilistically detect. A compile error is a guaranteed prevented production bug; tests only prove incorrectness when they fail, not correctness when they pass.
  • AI agents excel in compile-fix loops, not one-shot generation: Agents can autonomously compile Rust, parse detailed error messages (which explain why code fails), and iterate to correctness. This loop is faster than code review agents and more reliable than hoping the first TypeScript generation is bug-free.
  • Concrete example—fearless concurrency: A data race in TypeScript (100 threads incrementing a counter) compiles and runs but produces non-deterministic wrong answers. Rust compiler rejects it with "future cannot be sent between threads safely," pointing to the non-thread-safe Rc<RefCell<i32>> type—agent immediately knows to use a thread-safe type instead.
  • Compile time < code review time for catching bugs: Szoke claims Rust compilation (even if slow) is faster than running AI code review agents, which may miss bugs the compiler guarantees to catch. Trade-off favors upfront strictness over post-hoc validation.

Useful details

  • GitHub data: GitHub reported TypeScript became #1 language by contributor count in late 2023, attributing it to AI-assisted development adoption.
  • Rust safety guarantees mentioned: Strict type safety (no any escape hatch), null safety (explicit Option<T> types force checking), fearless concurrency (compiler checks thread-safe data sharing), memory safety.
  • Error message richness: Rust compiler not only says what failed but why (e.g., "this type is not Send") and often suggests fixes—valuable context for agents.
  • Murphy's Law framing: Without deterministic guardrails, any bug that can happen eventually will happen in production, regardless of human or agentic review quality.
  • Book reference: Yuval Noah Harari's Nexus discusses LLMs as first non-human language producers; prefers "alien intelligence" over "artificial intelligence" to emphasize cognitive difference.
  • Speaker background: Daniel Szoke is Rust SDK maintainer at Sentry (error tracking/monitoring company).

Caveats / counterpoints

  • No data on agent performance in Rust vs. Python/TypeScript: Szoke provides logical arguments and one concurrency example but no empirical comparisons of agent success rates, iteration counts, or time-to-working-code across languages.
  • Assumes agents can parse and fix all compiler errors reliably: Rust's strictness helps only if agents can actually interpret complex error messages and apply fixes correctly—no evidence provided that current agents do this well at scale.
  • Ignores ecosystem/library trade-offs: Python/TypeScript have vastly more libraries, frameworks, and examples for common tasks (web, data, AI). Rust's smaller ecosystem might slow agents down when they need to implement solutions from scratch vs. composing existing packages.
  • Compile time concerns hand-waved: Acknowledges Rust compile times are slow but dismisses concern by comparing to code review agents without quantifying either. For rapid prototyping, slow compile loops could negate iteration speed advantages.
  • Doesn't address learning curve for humans maintaining AI-generated Rust: If an agent generates Rust code, human reviewers still need Rust expertise to validate safety claims and fix issues—higher bar than TypeScript.
  • Single use case focus: Talk centers on correctness/safety but doesn't address other vibe-coding goals like rapid prototyping, throwaway scripts, or domains where dynamic languages excel (data exploration, scripting).

Ken relevance

High relevance for agent system architecture decisions. If Ken is building production AI agent systems that generate code autonomously (vs. human-supervised prototypes), this reframes the language choice:

  • Safety-critical agent outputs: If agents generate code that runs in production without heavy human review, Rust's compile-time guarantees could prevent entire classes of runtime failures Ken would otherwise need to detect/handle dynamically.
  • Agent workflow design: Suggests Ken should optimize agent loops for compile-fix iteration over one-shot generation quality—implies different prompting strategies, tooling (exposing compiler errors to agents), and success metrics (iterations to compile vs. first-pass success).
  • Counterargument to TypeScript-first defaults: Many AI coding tools/demos default to TypeScript for "ease"—this talk argues that's premature optimization. Relevant if Ken is choosing languages for AI-generated microservices, agents, or tooling where bugs have real cost.
  • Concurrency example directly applicable: If Ken's agents generate concurrent/parallel code (likely for performance), Rust's fearless concurrency would catch data races that TypeScript agents would ship.
  • Less relevant for: Prototyping, content generation, scripts, or cases where Ken reviews all AI output anyway. Rust overhead probably not worth it for throwaway code or non-production experiments.

Watch verdict

Watch fully. This is a novel, well-argued contrarian take on AI coding language choice with direct implications for how Ken should architect agent systems that generate production code. The concurrency example is concrete, the "alien intelligence" framing is memorable, and the compile-fix loop vs. one-shot generation insight could shift Ken's agent design philosophy. Worth the time if agent-generated code reliability matters to him.

Full transcript 2099 words · 16 min read
0:01

[SPEAKER_00] My name is Daniel Zouk.

0:14

SPEAKER_00

I'm the Rust SDK maintainer at Sentry, and I want to tell you why I think Rust is the ideal language for Vibe coding. The conventional wisdom on what language to use for agentic coding or Vibe coding, however you refer to it, Rust is probably not one of the first things you think of. Maybe you think chat GPT has a good idea on what's the best agentic coding language, given that it's also an agent of some sort. And it would tell you that there's no single number one language, but that Python is probably the top language. And there's a strong number two. It said JavaScript and TypeScript when I asked it.

0:27

SPEAKER_00

And I think that this is, in at least my experience, pretty true, although I would flip the order, because TypeScript seems to have come out as the top choice for agentic coding lately. And so there's even this article from GitHub that came out late last year. And it says that AI, they think that AI has pushed TypeScript to the number one language on GitHub, by contributor counts at least. So they know it's TypeScript as the number one language, and they strongly suspect that that's because of people using it for AI-assisted development. But why are these languages, Python, TypeScript, JavaScript, so ideal for Vibe coding? At least in this conventional wisdom.

0:46

SPEAKER_00

First of all, they're common and familiar languages. So they're usually the languages you would learn if you were learning programming from scratch. So they're easy for humans, and they also seem to be easy for LLMs. There's also a lot of frameworks, libraries, and examples out there. So that's helpful if you're building something new from scratch, of course, that you can build it on top of something. And it's helpful for humans, it's also helpful for agents. They're fast to scaffold and run. They're dynamic languages. They're interpreted, at least JavaScript and Python are. TypeScript maybe has some light compilation down to JavaScript or something.

1:22

SPEAKER_00

But it's pretty easy just to run it and see what it does, and then you iterate on that. And particularly for agents, the typing support is helpful so that the agent doesn't misuse types. But there's the any type that undermines that a little bit in TypeScript and typed Python. But overall, these languages, LLMs, the models themselves, are pretty good at outputting runnable code in the first try, because these languages are simple and they impose few constraints. So I think because of this fact that LLMs just seem to be good at writing them, people jump to these languages.

1:40

SPEAKER_00

But I think something that a lot of people, in my experience, don't question as much is whether this is even something we want to optimize for, right? The classic Vibe coding languages are easy for the models to write, but is that even a good thing? My argument is that the importance of it being easy for the model to write the language is overstated. And in fact, I would even say that in some cases, it's a bad thing that these languages are easy for the models to write. The dynamic and flexible nature of the languages is what makes it easy for the agent, or for the LLM, to write JavaScript, Python, TypeScript.

2:11

SPEAKER_00

But this same flexibility also makes it very easy to make mistakes, sometimes even obvious mistakes, sometimes less obvious mistakes. Adding typing is a helpful constraint, but that only gets you so far, because it only gives you the type safety, and also it's not a very strong type safety in TypeScript or Python. And this is, of course, a problem because LLMs are fallible. They will always be fallible because they are, by design, non-deterministic systems.

2:32

SPEAKER_00

So hopefully in the future, they get better at making mistakes less often, but I don't think this is something that would ever disappear entirely. And so just as the smartest humans make mistakes, we need to guard against human error, we're also going to need to guard against LLM error. One way that folks often would do that, especially also in the conventional vibe coding languages is adding tests. This is a huge help, but there are a lot of problems with only relying on having tests and code review agents.

2:40

SPEAKER_00

So, firstly, if you don't prompt the agent skillfully, it'll often write the tests after the implementation, and then you just end up testing implementation details without actually testing the behavior properly. Even with test-driven development though, tests usually can only prove incorrectness when they fail because it's impractical to test every single possible input combination. You can't prove that every input produces the correct output in a lot of cases. And then, of course, if LLMs are the ones generating the tests, they may make mistakes when writing those tests. And the same thing applies to coding review agents.

2:49

SPEAKER_00

And then, on a philosophical level, right? We all know AI stands for artificial intelligence, but there's this book called Nexus I recently read, and I can highly recommend it to anyone who hasn't read it yet. It's from an author Yuval Noah Harari. He's a historian, and he has a unique perspective on artificial intelligence. So, he's discussing human information that works all the way from Stone Ages to printing press to internet to now with LLMs, right? And he thinks LLMs are really unique because it's the first time we have something that's non-human that's able to produce human language.

2:53

SPEAKER_00

And a point he makes that really stuck with me is that he doesn't like that the A in AI is artificial because it understates how different LLMs and other AI technologies are from how humans think. And he actually likes to call it alien intelligence instead. Because the internal workings of how they think at a low level is different from how we think. LLMs predict tokens that come in streams, and it's a very powerful mechanism of thinking, but it's not how we think. And my point here is that the failure modes might be totally unexpected to us. And I'm sure if you've done any coding with AI, you might have had a situation where you got code that looked really nice. It might have had sensible variable names, good comments, and whatever. But when you take a look, something might not be right. There might be a subtle bug, or maybe it's relying on some heuristic when you could check the actual thing, and more reliably and more easily in some cases. So you really need to be careful with this, with LLM and agentic-based development, right? And then that brings me to Murphy's Law, which basically states that anything that can go wrong will go wrong eventually at some point, right? So if you are using a language without deterministic guardrails, even if you apply human review, agentic review, test a good testing process, if you don't have something that is an absolute deterministic guard against this, eventually you're going to have some failures. And in these languages like JavaScript, Python, TypeScript, where you lack these guardrails a lot of the times, you're going to have failures more often, right? And this brings me to Rust, which is a language with many constraints.

2:58

SPEAKER_00

And so for those of you who don't know anything about Rust, or don't know that much about it, some basic background, it's a compiled language. It's designed with safety and performance in mind. It wants to be as fast as C and C++, but it wants to be memory safe, type safe, and basically wants to have such a strict compiler that if the code compiles, you can be reasonably confident that a lot of different types of bugs are not present in your code.

3:07

SPEAKER_00

And that happens because the compiler is enforcing invariants like type safety, memory safety, concurrency, etc. And the language tries to be very beginner friendly. So Rust itself, I think people who haven't encountered it would have the perception that it's very advanced, but they try to make the language easy to learn. The compiler errors give you a lot of information on what went wrong and how to fix the problem. And so they provide a lot of context. And of course, this is really helpful when AI agents compile Rust code, hit an error, and then need to fix it.

3:22

SPEAKER_00

So as I mentioned, there's a lot of safety guarantees in Rust, right? First one worth mentioning is that the type safety is strict, you can't bypass it with some any type or an unchecked cast. Null safety is another big one. If you've come from other languages, there's no universal null value.

3:34

SPEAKER_00

If you want to have an option that, or a type that can be empty, you need to define it explicitly as an option type, and the compiler will force you to always check that the value is there before you access the inner value. And fearless concurrency, which is, I think, really powerful. And it basically means that the Rust compiler will check if you have any multi-threaded code, that any data shared between the threads is done, that that's all done in a thread safe way. And this is really just a small list.

3:40

SPEAKER_00

There's so many more things that the Rust compiler enforces. But I just want to give you all a quick example on fearless concurrency, because I think it's really powerful. So here's a little code example. Basically, we have a counter here, which is going to start with a value of zero. And we're going to create 100 threads here. And each time we're going to take the counter and add one to this inner value.

3:49

SPEAKER_00

So once all these threads finish, you would expect this to have a value of 100. Now there's a problem here, which is that these types here, they're designed for sharing mutable data, but only within a single thread. They're not synchronized for multi-threaded, safe access. So in a language like TypeScript, something like this might compile, it might run. And then you would only notice the problem when every once in a while you would get a value other than 100 out of this, right? And it might be, especially if this is a small part in a bigger application, it could be very difficult to debug where this data race is occurring. But in Rust, this just doesn't compile, you're going to get a compile error, and it will say error, future cannot be sent between threads safely. This future, so this little async block in here, is not send. And all send means is safe to be sent between threads, and it's not. So this error isn't that helpful, but if you scroll down in the error message, it'll explain further. And this is what's going to be really helpful to your AI agent, because it says, the value here, this counter value that was captured, it's not send. It has type rcref cell i32, and that's not send. And so if your AI agent when it just compiles your project, it'll get this compiler error, and it can immediately go and change this to a thread safe type, of which there's plenty in Rust. So of course, all these constraints come with a trade-off. Rust is harder for LLMs to get right on the first try, because there's so many rules they need to follow. But I think this is a good thing. That's because it's not just LLMs that write code. We put the LLM in an AI agent, it's in a loop, it can do things autonomously, and AI agents are very well suited to be able to compile their code, check any failures, and then go and fix them.

3:55

SPEAKER_00

And every compile error is potentially a bug that you avoid in your production code. So, with the Rust compiler, something I hear sometimes, people complain that compile times are slow. But I guarantee you that it's faster than letting an AI agent review your code, and it might not even find all the errors that the Rust compiler is guaranteed to find.

4:29

SPEAKER_00

So, we have a booth downstairs. Come by, feel free to ask questions about Sentry, or if you want to talk to me about the talk, you can also come by and I'm happy to chat. Thank you. Thank you. Adding typing is a helpful constraint, but that only gets you so far, because it only gives you the type safety, and also it's not a very strong type safety in TypeScript or Python. And this is, of course, a problem because LLMs are fallible. They will always be fallible because they are, by design, non-deterministic systems. So hopefully in the future, they get better at making mistakes less often, but I don't think this

5:16

SPEAKER_00

is something that would ever disappear entirely. And so just like the smartest humans make mistakes, that we need to guard against human error, we're also going to need to guard against LLM error. One way that folks often would do that, especially also in the conventional vibe coding languages is adding tests. This is a huge help, but there are a lot of problems with only relying on having tests and code review agents. So, firstly, if you don't prompt the agent skillfully, it'll often write the tests after the implementation, and then you just end up testing implementation details without actually testing

6:03

SPEAKER_00

the behavior properly. Even with that test-driven development though, tests usually can only prove incorrectness when they fail because it's impractical to test every single possible input combination. You can't prove that every input produces the correct output in a lot of cases. And then, of course, if LLMs are the ones generating the tests, they may make mistakes when writing those tests. And the same thing applies to coding review agents. And then, kind of more on a philosophical level, right? We all know AI stands for artificial intelligence, but there's this book called Nexus I recently read, and I can highly recommend it to anyone who hasn't read it

6:53

SPEAKER_00

yet. It's from an author Yuval Noah Harari. He's a historian, and he has kind of a unique perspective on artificial intelligence. So, he's discussing human information that works all the way from Stone Ages to printing press to internet to now with LLMs, right? And he thinks LLMs are really unique because it's the first time we have something that's non-human that's able to produce human language. And a point he makes that really stuck with me is that he doesn't like that the A in AI is artificial because it understates how different LLMs and other AI technologies are from how humans think. And he

7:43

SPEAKER_00

actually likes to call it alien intelligence instead. Because the internal workings of how they think at a low level is different from how we think. LLMs predict tokens that come in streams, and it's a very powerful mechanism of thinking, but it's not how we think. And my point here is that the failure modes might be totally unexpected to us. And I'm sure if you've done any coding with AI, you might have had a situation where you got code that looked really nice. It might have had sensible variable names, good comments, and whatever. But when you take a look, something might not be right. Like there might be

8:25

SPEAKER_00

a subtle bug, or maybe it's relying on some heuristic when you could check the actual thing, and more reliably and more easily in some cases. So you really need to be careful with this, with LLM and agentic-based development, right? And then that brings me to Murphy's Law, which basically states that anything that can go wrong will go wrong, will go wrong, eventually at some point, right? So if you are using a language without deterministic guardrails, even if you apply human review, agentic review, test a good testing process, if you don't have something that is a absolute deterministic guard against this, eventually

9:12

SPEAKER_00

you're going to have some failures. And in these languages like JavaScript, Python, TypeScript, JavaScript, where you lack these guardrails a lot of the times, you're going to have failures more often, right? And this brings me to Rust, which is a language with many constraints. And so for those of you who don't know anything about Rust, or don't know that much about it, some basic background, it's a compiled language. It's designed with safety and performance in mind. It wants to be as fast as C and C++, but it wants to be memory safe, type safe, and basically wants to be such, like, it wants to have such a strict compiler that if the code compiles,

10:02

SPEAKER_00

you can be reasonably confident that a lot of different types of bugs are not present in your code. And that happens because the compiler is enforcing invariants like type safety, memory safety, concurrency, etc. And the language tries to be very beginner friendly. So Rust itself, I think people who haven't encountered it would kind of have the perception that it's very advanced, but they try to make the language easy to learn. The compiler errors give you a lot of information on what went wrong and how to fix the problem. And so they provide a lot of context. And of course, this is really helpful when AI agents compile Rust code, hit an error, and then need to fix it.

10:52

SPEAKER_00

So as I mentioned, there's a lot of safety guarantees in Rust, right? First one worth mentioning is that the type safety is strict, you can't bypass it with some any type or an unchecked cast. Null safety is another big one. If you've come from other languages, there's no universal null value. If you want to have an option that, or a type that can be empty, you need to define it explicitly as an option type, and the compiler will force you to always check that the value is there before you access the inner value. And fearless concurrency, which is, I think, really powerful. And it basically means

11:37

SPEAKER_00

that the Rust compiler will check if you have any multi-threaded code, that any data shared between the threads is done, that that's all done in a thread safe way. And this is really just a small list. There's so many more things that the Rust compiler enforces. But I just want to give you all a quick example on fearless concurrency, because I think it's really powerful. So here's a little code example. Basically, we have a counter here, which is going to start with a value of zero. And we're going to create 100 threads here. And each time we're going to take the counter and add one to this inner value.

12:26

SPEAKER_00

So once all these threads finish, you would expect this to have a value of 100. Now there's a problem here, which is that these types here, they're designed for sharing mutable data, but only within a single thread. They're not synchronized for multi-threaded, safe access. So in a language like TypeScript, something like this might compile, it might run. And then you would only notice the problem when every once in a while you would get a value other than 100 out of this, right? And it might be, especially if this is a small part in a bigger application, it could be very difficult to debug where this data race is

13:16

SPEAKER_00

occurring. But in Rust, this just doesn't compile, you're going to get a compile error, and it will say error, future cannot be sent between threads safely. This future, so this little async block in here, is not send. And all send means is safe to be sent between threads, and it's not. So this error isn't that helpful, but if you scroll down in the error message, it'll explain further. And this is what's going to be really helpful to your AI agent, because it says, oh, the value here, this counter value that was captured, it's not send. It has type rcref cell i32, and that's not send. And so if your AI agent,

14:06

SPEAKER_00

when it just compiles your project, it'll get this compiler error, and it can immediately go and change this to a thread safe type, of which there's plenty in Rust. So of course, all these constraints come with a trade-off. Rust is harder for LLMs to get right on the first try, because there's so many rules they need to follow. But I think this is a good thing. That's because it's not just LLMs that write code. We put the LLM in an AI agent, it's in a loop, it can do things autonomously, and AI agents are very well suited to be able to compile their code, check any failures, and then go and fix them.

14:55

SPEAKER_00

And every compile error is potentially a bug that you avoid in your production code. So, and with the Rust compiler, like something I hear sometimes, people complain that compile times are slow. But I guarantee you that it's faster than letting an AI agent review your code, and it might not even find all the errors that the Rust compiler is guaranteed to find.

15:55

SPEAKER_00

So, we have a booth downstairs. Come by, feel free to ask questions about Sentry, or if you want to talk to me about the talk, you can also come by and I'm happy to chat. Thank you. Thank you.

Reading tools

Type to find a passage

Appearance
Ask this transcript

Add a note