How I render HTML in Elysia

For small, server-heavy web applications that primarily read from databases and generate reports, separating frontend and backend often adds unnecessary complexity. Instead of creating a dedicated frontend project, I prefer rendering HTML directly from the server side. My @thai/html library provides a solution with tagged template literals, automatic string escaping, and streamable rendering support.

Here’s the Elysia plugin to integrate HTML rendering:

// ./elysiaPlugins/html.ts
import { fromAnyIterable } from '@sec-ant/readable-stream'
import { Hypertext, renderHtmlStream, type Html } from '@thai/html'
import { Elysia } from 'elysia'

async function* toBinary(
  stream: AsyncIterable<string>
): AsyncIterable<Uint8Array> {
  for await (const chunk of stream) {
    yield new TextEncoder().encode(chunk)
  }
}

export function htmlResponse(html: Html) {
  return new Response(fromAnyIterable(toBinary(renderHtmlStream(html))), {
    headers: {
      'Content-Type': 'text/html; charset=utf-8',
    },
  })
}

export const htmlPlugin = new Elysia({ name: 'html' })
  .mapResponse(async ({ response }) => {
    if (response instanceof Hypertext) {
      return htmlResponse(response)
    }
  })
  .as('scoped')

And here’s how to use the plugin:

import { html } from '@thai/html'
import Elysia from 'elysia'
import { htmlPlugin } from './elysiaPlugins/html'

export default new Elysia().use(htmlPlugin).get('/', () =>
  layout({
    title: 'Elysia HTML Example',
    body: html`<h1>Hello, Elysia!</h1>`,
  })
)

function layout({
  head,
  title,
  body,
}: {
  head?: Html
  title: string
  body: Html
}) {
  return html`
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <title>${title}</title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        ${head}
      </head>
      <body>
        ${body}
      </body>
    </html>
  `
}