Remote-Url: https://blog.yusu.ke/hono-htmx-cloudflare/ Retrieved-at: 2023-07-21 08:34:30.052269+00:00 Jul 21, 2023As a former backend engineer, I sometimes find React complex. Moreover, as a framework developer, creating a hydration mechanism can be troublesome. But we often end up using React.One of the main advantages of using React is JSX. At first, JSX seems strange - “Why are HTML tags in JavaScript!!!” However, once I get used to it, I find that JSX is flexible and comfortable to use.Today, I’ll introduce a tech stack where the main point is using JSX purely as a server-side template engine. This means we can useJSX without React.Hono JSX MiddlewareHono- a JavaScript framework for edges - includesJSX middleware. You can write HTML with JSX but it’s strictly for server-side rendering, not for the client. As such, it serves as a template engine, much like Handlebars, EJS, mustache, or others.constapp=newHono()app.get('/', (c)=>{returnc.html(

Hello!

)})A Hono app can run on edge servers likeCloudflare Workers,Fastly[email protected], orDeno Deploy. This allows for incredibly fast server-side rendering. Moreover, it doesn’t perform “hydration” for JavaScript, meaning you don’t lose user experience without the need for SPA transition. This combination of edge-based SSR and the absence of hydration makes for a very speedy setup.htmxhtmxis a library that enables Ajax without the need to write JavaScript.Click MeIt’s comparable toHotwire, which is used by Ruby on Rails. However, unlike using React with a REST API, htmx can easily integrate with server-side JSX, making it simpler to create interactive experiences.The stackThe entire stack includes the following components:Hono + JSX MiddlewarehtmxZodTailwind CSSCloudflare WorkersCloudflare D1Cloudflare D1is a database service that runs SQLite on Cloudflare edges. Although it’s currently in “alpha” status and not recommended for production use, it’s already fast and perfectly suitable for Proof of Concept (PoC) projects.In the example below, I useZodto validate incoming values. Hono’s Zod Validator Middleware is incredibly useful as it integrates with Hono, allowing us to easily get the types of validated values.html.jsI must express my gratitude. This idea is based on@dctanner’s tweet. He named it the ”html.js” stack. You can find it in this repository:https://github.com/dctanner/htmljs-todo-example100 lines Todo appIt’s amazing. I was able to create a real Todo App example that inserts and deletes data in D1 SQLite on the edge with just100 linesof code. It’s fast (~100ms) and lightweight (gzipped worker size:22 KB)!Here is the demo:Build size:CodeNormally, when I have to show an example code, I have to choose specific parts of the code and paste a few lines. However, this example is just 100 lines, so I’ll show the entire code.comonent.tsx:import{ html }from'hono/html'exportconstLayout=(props:{children:any})=>html`Hono + htmx

Todo

${props.children}
`exportconstAddTodo=()=>(Submit)exportconstItem=({title,id}:{title:string;id:string})=>({title}Delete

)index.tsx:import{ Hono }from'hono/quick'import{ z }from'zod'import{ zValidator }from'@hono/zod-validator'import{ Layout, AddTodo, Item }from'./components'typeBindings={DB:D1Database}typeTodo={title:stringid:string}constapp=newHono<{Bindings:Bindings}>()app.get('/',async(c)=>{const{results}=awaitc.env.DB.prepare(`SELECT id, title FROM todo;`).all()consttodos=resultsasunknownasTodo[]// Currently, should fix a type mismatch.returnc.html({todos.map((todo)=>{return})})})app.post('/todo',zValidator('form',z.object({title: z.string().min(1)})),async(c)=>{const{title}=c.req.valid('form')constid=crypto.randomUUID()awaitc.env.DB.prepare(`INSERT INTO todo(id, title) VALUES(?, ?);`).bind(id, title).run()returnc.html()})app.delete('/todo/:id',async(c)=>{constid=c.req.param('id')awaitc.env.DB.prepare(`DELETE FROM todo WHERE id = ?;`).bind(id).run()c.status(200)returnc.body(null)})exportdefaultappIsn’t it elegant?You can find the entire project here:https://github.com/yusukebe/hono-htmxAm I talking about PHP?Perhaps, you’re wondering:Are you talking about PHP?To which I’ll answer:No. But it’s quite similar!It really feels like PHP, or perhaps Ruby on Rails. But I think PHP is not bad. Moreover, this stack has several advantages for me:It runs on the edges.I can use JavaScript/JSX.I can avoid spaghetti code by organizing the code well.As I mentioned at the beginning, I used to be a backend engineer, so this approach to website creation is more familiar and comfortable for me. It’s simple and clean.Going forwardThere are a few things we need to work on to stabilize this stack. One is enabling file-based routing. Also, I’m not sure if using Hono’s JSX middleware is the best approach, maybe Preact would be a better choice.Anyway, this stack has a nostalgic yet new feeling to it. Oh, I’ve forgotten one thing we need to do. We should name this stack!ThanksAgain, thank you to@dctannerfor the inspiring idea. I also recommend checking out his repository:https://github.com/dctanner/htmljs-todo-example