Why I Ended Up Building My AI Agent in TypeScript, Not Python

While building an agent for a project recently, I hit a fork in the road that a lot of JavaScript devs know well.
My app was in TypeScript. Frontend, backend, all of it. But for the agent part, the entire world pushes you toward Python. The tutorials, the libraries, the job postings — everything assumes AI happens in Python. So I had two options: stand up a Python layer just for the agent, with its own separate microservice, or stay in TypeScript and see how far LangGraph.js could take me.
I went and did the research before deciding. And the surprise was that, for the kind of agent I was building, TypeScript didn't just keep up with Python. In several places, it actually beat it.
Here's what I found, because if you're a JS dev, you might be about to make the same call.
One codebase, no borders to cross
The first thing that made me hesitate on Python was the obvious one: it would mean two languages and two services to maintain. My agent state in Python, my app in TypeScript, and me serializing data between the two every time they crossed the border. By staying in TS, I share the exact same types from the React interface all the way down to the graph state. One codebase, no duplicated schemas, no bugs at the seams. That alone tilted the scale.
Type safety against an unpredictable model
Next came something I didn't expect: type safety against an unpredictable model. AI is stochastic — you never know for certain what it's going to hand back. In TypeScript, I define the graph state with strict types and validate the model's outputs with Zod at runtime, before they ever touch global state. If the model returns something malformed, I catch it right there instead of watching the app crash three steps later. That control gave me more peace of mind than anything else.
Where it runs matters
Then there's the question of where it runs. My agent lived inside a web product that needed to respond fast. LangGraph.js runs on Vercel Edge, on Cloudflare Workers, on Lambda — close to the user, with minimal cold starts. Python doesn't reach those environments. For an agent embedded in a web app, that infrastructure detail matters a lot.
Concurrency, the real winner
And the last point: concurrency. Orchestrating an agent is mostly waiting on network responses — calls to the model, to the vector store, to APIs. Node's event loop handles thousands of those connections and token streaming with a much lighter memory footprint than a synchronous server. That's exactly the kind of workload an agent produces.
Where Python still wins
Now, to be fair, it's not all in favor of TypeScript. And this is where I want to be clear, so nobody goes off and builds the wrong thing.
If my agent had needed to train or run local models, do fine-tuning, or do heavy data manipulation with Pandas and NumPy, I would have gone straight to Python, no question. That ecosystem belongs to Python and has no rival there. If your team is data scientists who already live in Python, staying there is the right call. And new LangChain features usually ship in Python first. None of that is up for debate.
In fact, a lot of the time the answer isn't picking one or the other. It's common to see architectures where the heavy agent runs in Python on LangGraph Server, and a TypeScript frontend consumes it through the official SDK with autogenerated types. Each language doing what it does best.
My case, and where most agents are heading
But my case — a stateful agent with persistence and human intervention, living inside a web app — is exactly where TypeScript shines. And it's not a rare case. It's where most of the agents people will actually use are headed.
In the end, I stayed in TypeScript. I never added the Python layer. And the agent runs in production without a hitch.
I'm sharing this because if you're a JavaScript dev and you think you need to learn Python from scratch to get into agents, that's not true. For this kind of project, the language you already know is a serious option — and in more than a few cases, the best one.