I didn’t want to rewrite the backend.
Three months ago I had a perfectly functional NestJS backend. It handled all the Facebook webhooks. It connected to the database. It calculated prices correctly. It worked. Sort of.
But every time I went to add a new endpoint, I felt the exact same dread I feel when I open a 1000-page government form. I knew there would be 30 minutes of boilerplate before I could write the single line of code that actually did something.
This is the part where every tech blogger says “and then I rewrote everything in Rust!”
I didn’t rewrite everything in Rust. I rewrote everything in Bun and Hono. And it’s the best technical decision I’ve made on this project so far.
“The best framework is the one you don’t notice”
The Decision Matrix
I had three real options.
The Contenders:
- Keep NestJS on Node.js
- Rewrite in .NET 10
- Move to Hono/ElysiaJS on Bun
The Rubric:
This is the part most people skip. I wasn’t optimizing for “best performance ever” or “most GitHub stars”. I was optimizing for exactly four things:
- I am one person. The framework must get out of my way.
- Full stack TypeScript. No context switching between languages.
- AI coding agents must be good at writing code for it.
- Strict types everywhere, avoid runtime issues.
Let’s give each one a fair fight.
Option 1: Keep NestJS
This was the default. I already had 50000 lines of working code. I knew all the weird quirks. I could have just kept going.
But there were problems that wouldn’t go away:
Build times: 20 seconds. Every single change. Every time I saved a file, I had enough time to make coffee, drink half of it, and come back before the server restarted. I wasted 3-4 hours a week just waiting for builds.
ESM hell: Half the ecosystem is ESM now. Half is still CommonJS. Every time I added a new package it was a 50/50 shot whether it would work.
Want to import a relative file? You can’t write import './auth.service'. You have to write import './auth.service.js'. With the .js extension. Even though the actual file on disk is .ts.
Want to use src aliases? Good luck. Some tools respect them. Some don’t. Some only respect them half the time. I spent 12 hours last month debugging why one single package wouldn’t import correctly. Nobody should have to think about module systems in 2026.
Bun fixes all of this. Just write the import. It works. No extensions. No flags. No type: module in package.json. No __esModule hacks. It just works.
DTO boilerplate: For every endpoint I wanted to write, I needed:
- An interface
- A DTO class with 7 decorators
- A validation schema
- A separate OpenAPI definition
- A transformer
All for an endpoint that literally just takes two numbers and returns a price. It was madness.
Option 2: Rewrite in .NET 10
Let me be extremely clear here: I’m a .NET developer and I love it.
If you are a .NET developer reading this, I get it. I totally get it.
One standard routing system. Two JSON parsers total in the entire ecosystem. Strict types by default. Amazing tooling. Predictable. No drama. If I was working on a team of 5+ developers, if this was an enterprise product, if I planned to hire people, .NET 10 would be the obvious, correct, responsible choice.
There are exactly zero technical arguments against .NET for this kind of backend. It’s faster. It’s more stable. It has better standard library. The AOT compilation. For 95% of all backend projects being built today, .NET is the correct choice for me.
But I am not building 95% of backend projects. I am building QuotyAI. And I have one extremely weird constraint that almost no one else has:
90% of the code written for this project is not written by me. It’s written by AI coding agents.
And here is the uncomfortable truth that no one will tell you: AI coding agents are quite bad at writing good C#.
They can write C# that compiles. They can write C# that runs. But every single time I asked Claude, GPT, or GLM to write me a simple .NET endpoint, it would come back with 2019-style enterprise boilerplate. Three interfaces. Two abstract classes. A factory pattern. And somewhere buried 12 levels deep, the three lines of code that actually did what I wanted.
I would spend 15 minutes deleting all the garbage just to get to the actual logic. For a solo founder who writes 10 endpoints a day, that’s 2.5 hours a day wasted deleting boilerplate that the AI added for absolutely no reason.
And there’s a second, even bigger reason that almost no one talks about:
Every single important AI framework ships TypeScript first.
LiveKit. LangChain. OpenAI SDK. Anthropic SDK. Deepgram. All of them get new features in TS 3-6 months before they show up in .NET. All the examples are in TS. All the documentation is in TS. All the bug fixes land in TS first.
When LiveKit released their realtime voice agent API last month, the TypeScript SDK was available on day one.
For a product that lives and dies by being able to use the latest AI tools as soon as they come out? That difference is not trivial.
And let’s be perfectly honest about something else: you are 100% correct.
.NET is better than TypeScript for background jobs. Sagas. Distributed transactions. Reliable queues. All the boring, hard, important stuff that big enterprise systems need. The TypeScript ecosystem is still 5-10 years behind here. There is no argument. If you are building a banking system, an ERP, or anything that needs to reliably process 10 million background jobs a day.
But I am not building that. I am building an AI product where 90% of the complexity is in API endpoints and AI agent logic. Not so much background processing.
For teams? For enterprise? Use .NET. It is objectively the better general purpose backend framework. For me, right now, building this specific product in 2026? It was the wrong choice.
“AI doesn’t write enterprise patterns - it writes boilerplate. Your framework choice should account for this.”
Option 3: Hono on Bun
I kept an eye on it since it was released but never used it. Same for Deno.
I also tried ElysiaJS. It’s very popular, very fast, and has amazing documentation. But I hated the functional style of routes. All the pipe chaining, method chaining, and functional composition just didn’t click for me.
I’m an old-fashioned developer. I like OOP. I like dependency injection. I like patterns that have worked for 30 years. Hono lets me write code that looks like normal code, not like some academic functional programming experiment.
Then I tried it.
bun dev starts in 800ms. Not 8 seconds. I save a file, and the server is restarted before my finger leaves the ctrl key.
No module system drama. Everything just imports. No __esModule flags. No require() vs import fights. It just works.
And Hono? Hono doesn’t do magic. It doesn’t do dependency injection. It doesn’t have a 400 page documentation site.
It does exactly three things:
- Routes requests
- Validates input
- Generates OpenAPI schemas
And it does all three without making me write any boilerplate.
The Implementation Deep-Dive
The biggest win wasn’t performance. It was schema generation.
With NestJS I would write this:
@ApiProperty()
@IsNumber()
@Min(1)
@Max(365)
nights: number;
@ApiProperty()
@IsNumber()
@Min(0)
cleaningFee: number;
And then I would still have to write the Zod schema separately. And then I would still have to write the TypeScript interface. Three sources of truth. Always out of sync.
With Hono and hono-openapi I write this once:
const CreateBusinessEntityFactsSchema = z.object({
facts: z.array(z.object({
content: z.string(),
tags: z.nativeEnum(FactTagEnum).array()
}))
});
That’s it. That’s the entire definition.
Hono automatically:
- Validates all incoming requests at runtime
- Generates perfect OpenAPI documentation with descriptions and examples
- Gives me full compile-time TypeScript types via
z.infer<typeof Schema> - Returns proper 400 errors with exactly which field was wrong and why
Want to strip extra fields from requests? .strip(). Want to make something partial? .partial(). Want to merge two schemas? .and(). All native. All built-in.
No decorators. No DTO classes. No 7 separate decorators per field. No magic. Just one source of truth.
The entire rewrite took 3 days. Not 3 weeks. 3 days. I deleted 2000 lines of boilerplate code and the application worked exactly the same. But now it builds in 2 seconds instead of 45.
This isn’t theoretical. Every single endpoint in QuotyAI works exactly like this. The route file that handles all the business fact extraction, OCR, translation, and AI hint generation? It’s 950 lines long.
In NestJS that same functionality would have been 3000+ lines spread across 12 different files. Controllers. DTOs. Providers. Modules. Interfaces. All for exactly the same functionality.
If I had to do this again? I would have done it 2 months earlier. I wasted so much time fighting NestJS when I could have just been building features.
The Cost of Admission
This isn’t a “everyone should use Bun and Hono” post. This is what works for me.
Every choice has tradeoffs. Here’s what I give up:
- Smaller ecosystem: No pre-built packages for every edge case. I write code myself instead of debugging giant abstractions.
- Less Stack Overflow: When something breaks, there are 3 answers instead of 1000. One of them is usually mine.
- No guard rails: Hono doesn’t stop you from writing bad code. It just gets out of your way.
- Occasional bugs: Things break. The MongoDB driver had a memory leak last week. It got fixed.
.NET is more stable. More mature. Better for teams. If that’s what you need, use it. You’re right.
The Verdict
For me, right now, this is the perfect stack.
I can write an endpoint, add validation, get full types, and have OpenAPI documentation in 2 minutes. Not 20.
Claude, GPT, and GLM understand Hono perfectly. They write clean, simple code without all the enterprise garbage.
I use the exact same TypeScript types on the backend, in the browser extension, on the frontend, and even in the landing page. No copying. No syncing. Just one definition.
This stack doesn’t optimize for 100 developers. It optimizes for one developer who needs to move very fast.
That’s exactly what QuotyAI needs.
I don’t need a framework that can scale to 100 engineers. I need a framework that lets one engineer scale to 1000 users.
“Optimize for your constraints, not everyone else’s best practices.”
And right now, Bun and Hono are the best tools for that job.
Frequently Asked Questions
Why choose Bun and Hono over NestJS?
Bun eliminates ESM module drama and provides 800ms startup times, while Hono removes boilerplate without sacrificing type safety - critical for solo founders moving fast.
How does AI coding agent performance affect framework choice?
AI agents write 30-50% less boilerplate for Hono compared to .NET or NestJS, saving 2.5+ hours daily on cleanup of unnecessary enterprise patterns.
What are the tradeoffs of using Bun and Hono?
Smaller ecosystem, fewer Stack Overflow answers, no guard rails, and occasional bugs - but these are acceptable tradeoffs for solo founders prioritizing speed.
Technical citations and references: