← Back to list

How I Accidentally Made a Bun CLI That Violates Hono’s Best Practices (And Why That’s Okay)

Introducing Hayai — The Fast Bun + Hono Boilerplate Generator I Built for Fun! Or so at least that’s how I wanted the title to be.

Andre Ho · 2026-01-23 04:51 · 1 claps · 7.1 min read
#buns #hono #prisma-orm #npm-package
Open on Medium ↗

How I Accidentally Made a Bun CLI That Violates Hono’s Best Practices (And Why That’s Okay)

Introducing Hayai — The Fast Bun + Hono Boilerplate Generator I Built for Fun! Or so at least that’s how I wanted the title to be.

So I’m on summer break, and at some point I remembered that one of my friends once built a Bun version manager. If you haven’t seen it, check out Bum — Bun Version Manager by my friend Owen: https://github.com/owenizedd/bum

Watching him build something clean, useful, and Bun-native made me think “Maybe I should try making something too.”

And so, like many developers, I went down the Bun rabbit hole.

People said it was fast, clean, and superior to Node.js and Deno in terms of performance (I can’t fully verify that as I didn’t benchmark anything). “I’ll just experiment,” I told myself.

Famous last words...

So I picked the stack, Hono and Prisma.

I still remember discovering Hono around 2022 from a Medium article, back then my machine was still running Windows, and getting Hono to work meant messing around with WSL.

Fast forward to now:

  • Hono is more mature
  • I’ve fully moved to Linux

There was nothing stopping me anymore.

My motivation was simple.

I once used Laravel’s Artisan, and honestly?

I was impressed.

If you’ve done freelance work or side projects, you probably know the pain:

  • Copy-pasting boilerplate
  • Doing find-and-replace
  • Forgetting to rename one field
  • Ending up with products stored inside a posts table

Sure, you can fix this quickly with Copilot or Cursor now. But I wondered:

What if I wanted a clean, old-school generator way. No AI, just deterministic code?

The idea behind Hayai is simple:

  • You describe your model in configuration file
  • A generator produces working code. The controllers, routes, validation and test
  • You only need minimal tweaking to suit your interest

I wanted a way to spin up a full Hono + Prisma API with authentication, routes, and schemas without copy-pasting boilerplate every time.

That’s how Hayai was born as the project title.

Hayai (早い) means “quick” in Japanese, since Hono itself is also named after “flame.”

But first, before I have a code generator, of course I need to have a “proven” and working code as a base. So I scrambled through all my old projects and found one Typescript API project. Great! since Hono works just like a typescript expressjs project this means I can technically “port” the code to Hono.

Long story short after only skimming through the documentations, I just used my feeling and converted my code and after testing that it works I quickly get to work on the code generator.

The thing is, I don’t really know how to implement a code generator. So my solution is rather crude. Get the generator a template file, then the generator will find the “marker anchors” that marks a section in the template and just populate in-between the markers. I didn’t know how “proper” code generators worked at the time so I built the simplest one that could possibly work. After meddling around and consulting ChatGPT to seek validation for my idea. I managed to get everything done after days of playing around.

So… How Does Hayai Actually Work?

Hayai uses a very simple, template-based approach to code generation.

No local LLM magic.

No compiler tricks.

The “black magic” is just configuration + templates + a lot of string replacement.

At a high level, it works like this:

Run hayai initto initialize the project directory. Hayai will copy a template project root for you.

Using hayai module:add <name> you can add a module inside templates/<name>.hayai.json. For example running hayai module:add post will create this snippet

{
  "name": "Post",
  "fields": [
    { "name": "title", "type": "String" },
    { "name": "content", "type": "String" },
    { "name": "authorId", "type": "String", "relation": "User.id" }
  ]
}
  1. You describe a module in .hayai.json file. Which includes things like: field names and data types; relations; which CRUD routes you want per above snippet.
  2. Hayai then reads a set of .hayai template files. Which is literally just a typescript files containing placeholders like *{moduleName} and {{SECTION_CRUD_METHODS}}.*There’s no real templating engine like jinjja or pug here, just marker sections and string replacement.
  3. After that when you run hayai module:build the generator just replaces those placeholder. Based on the configuration Hayai just fills in:
  • Controller methods
  • Route definitions
  • Zod validation schema
  • Test cases
  • Prisma model definitions
  1. The generated files are written directly in your project directory. Controllers go into src/controllers , routes go to src/routes , tests go to src/tests
  2. Prisma models are appended to schema.prisma .

After that you just need to run

bun run db:generate
bun run db:migrate

That’s it.

It’s just a configuration-driven, template-heavy, and intentionally simple (thanks to ChatGPT for helping me build the regex I needed to locate the markers in my template).

And by the way, that also means it is very fragile as templates will obviously break if you change something carelessly. If you need a complex stuff or complex logic, human intervention is 100% needed. It’s literally just a “generate once, then tweak” workflow.

But to spin up the APIs boilerplate quickly?

It worked surprisingly well!

Publishing to npm (aka: Learning the Hard Way)

Publishing my first npm package was another adventure.

From:

  • Creating an npm account
  • Learning about scopes
  • Publishing
  • Failing
  • Find out you need a token
  • Publishing again
  • Fail again
  • Realizes you need to bump up the version otherwise changes will be rejected
  • Realizes that npm does not automatically pull update from github and you need to run npm publish (or set it in your CI/CD pipeline)
  • Continuous cycle of publishing and finding out something is wrong

If you look at the commit history here. You’ll see something… questionable.

Yes! I acknowledge that pushed directly to main (or master if you are using the old github terms)

But before anyone calls the programming police or accusses me committing blasphemy against Git gods. I have worked as a software engineer before. I do know the proper workflow. Branches, pull request, peer reviews — All of that, alright?

This was simply a solo project with “Let’s see if this works” energy of a side project and I didn’t want to slow myself down with all the proper “rituals”.

That being said. I do not recommend pushing directly to main either. I mean, bad habits always can stick around and this is not something you want to normalize, especially if you work alone.

In most profesional environments, you would not be able to do this anyway. As organizations usually have branch protection rules in place, so you can’t commit (pun intended) this crime.

Anyway, back to the topic.

Eventually after multiple fixes and retries finally it worked.

Seeing your own package live on npm is a genuinely fun moment.

The “oops” moment:

Everything was sunshine and rainbows… until I realized that I had actually written an Express.js app cosplaying as a Hono app.

One big controller class, lots of methods and zero awareness of Hono’s preferred style because what’s in my mind back then was “Okay, this seems like a port of Typescript”. Then I found out about Hono best practices in https://hono.dev/docs/guides/best-practices and realized I have violated almost every one of them.

Turns out, Hayai is fast. Just not in the direction that Hono intended.

If Hono was a racetrack, I was driving a race car at full speed only for the referee to shout:

“Hey! Wrong way”

And that’s okay

At least subjectively according to myself. The goal was never about perfection but the learning of building a CLI, wire up bun and understand code generation.

Bun and Hono are fast, but they’re also still relatively niche.

If you look at most professional environments today, you’ll still find far more Express, or platforms like Go services and Java Spring Boot powering production systems than Hono. That’s just the current reality of the ecosystem.

In practice, Hono probably will shows up in places like:

  • student projects
  • experiments
  • learning environments
  • or among my fellow tech geeks who just enjoys learning, trying and benchmarking new tools.

And it’s not in any sense a bad thing at all. After all an ecosystem can only grow from experimenting.

And so, Hayai is not for production right now. It’s for learning, tinkering, and going “wow, it actually runs!” moments.

It’s Prisma-only, template-fragile, and still built with ExpressJS muscle memory.

I should also admit something else:

This article has been sitting in my Medium drafts for more than a month.

I genuinely forgot about it until I published my previous article about Exposing Your Local Web App to the Internet with Cloudflare Tunnel and I saw “Drafts 1” and went,“Oh right… I wrote that.”

So this post is less of a roadmap and more of a snapshot. Just a record of what I learned at that point in time.

And honestly, by the time this article is published, I probably won’t fix most of these issues anymore.

I’ve already stumbled into another side project that caught my interest, and fixing a majorly broken side-project code generator would take far more time than I realistically have. With a limited break, I’d rather spend that time exploring something new than trying to force Hayai into something it was never meant to be (yet).

Not because I don’t want to “perfect” it. There’s nothing wrong with being a perfectionist. But given a limited break window, I treated this as an engineering trade-off: document what I learned, ship what works, and move on, instead of half-fixing something that genuinely deserves more time. Especially when changing already working templates risks breaking everything and sending me back into a full re-test cycle.

A Note to Fellow Devs

If you’re experimenting with Bun, check out Bum, a version manager that inspired me to try this in the first place. And if you ever wanted to make your own CLI or code generator, do it.

Even if you mess up the best practices. Even if you skim the docs.

You’ll learn far more than you expect.

I definitely did. I learned the hard way that skimming documentation is not how you reach perfection. But it is how you eventually understand why best practices exist, how they should be implemented, and when your own code violates them.

Hayai is my first npm package. Fast, imperfect, and full of accidental Express muscle memory. It’s literally just accumulation of “let’s see if this works” being thrown at it.

I hope it inspires someone else to build their own little CLI chaos too.

Try it if you want

You can give it a try if you want! Checkout the npm and github repo here

https://www.npmjs.com/package/@andre_hrs/hayai-cli

[embed]GitHub - AndreHrs/hayai Contribute to AndreHrs/hayai development by creating an account on GitHub.github.com


메타데이터
post_id
0f7ab6119441
slug
how-i-accidentally-made-a-bun-cli-that-violates-honos-best-practices-and-why-that-s-okay-0f7ab6119441
url
https://medium.com/@andre_ho/how-i-accidentally-made-a-bun-cli-that-violates-honos-best-practices-and-why-that-s-okay-0f7ab6119441
canonical_url
https://medium.com/@andre_ho/how-i-accidentally-made-a-bun-cli-that-violates-honos-best-practices-and-why-that-s-okay-0f7ab6119441
author_url
https://medium.com/@andre_ho
status
ok
fetched_at
2026-06-09 15:37:30