Show HN:我用 TypeScript 重写了 PHP(演示)
Show HN: I reinvented PHP in TypeScript (demo)

原始链接: https://github.com/vseplet/morph

Morph是一个可嵌入的全栈库,用于构建无需构建步骤的超媒体驱动应用程序,专为Deno、Bun和Node.js环境设计。它利用HTMX进行服务器端渲染,融合了SSR、SPA和岛屿架构的优点,同时遵循纯HTML、CSS和JS。它最初是为了优化Telegram Web App的开发而创建的,因为传统的前端技术栈对于小型项目来说过于复杂。 其关键特性包括:无需构建步骤、客户端JavaScript代码极少、组件的服务器端渲染,以及组件能够调用自身返回超文本的API的能力。组件可以嵌套并独立重新渲染,形成一个层次结构。当无需分离前端和后端时,Morph尤其出色,使其成为Telegram机器人、桌面应用程序或需要动态UI而无需完整前端技术栈的内部工具的理想选择。它目前运行在Hono之上,未来可能会支持其他后端。

Hacker News 上的一篇文章展示了 Morph,这是一个用 TypeScript 编写的实验性全栈 HTML-first 库,旨在通过直接从服务器渲染 HTML 来简化 Web 开发。Morph 为 Deno、Node 和 Bun 而构建,无需 React 等前端框架、Vite 等构建工具以及复杂的配置。创建者 vseplet 构建它的目的是为了避免现代前端开发的复杂性,尤其是在 Telegram 网页应用和内部工具等应用中。虽然目标是简化流程并避免依赖 JSON/API 的重量级架构,但一位评论者指出,这种方法类似于旧的 PHP 实践,其中业务逻辑与模板混杂在一起,这种实践在现代 PHP 开发中由于可维护性问题而 largely 被放弃。创建者承认该库主要是为了解决他自己在前端复杂性方面遇到的问题。

原文

JSR GitHub commit activity GitHub last commit

This package is under development and will be frequently updated. The author would appreciate any help, advice, and pull requests! Thank you for your understanding 😊


Morph is an embeddable fullstack library for building Hypermedia-Driven Applications without a build step, based on HTMX.

Morph combines the best of SSR, SPA, and islands architecture, while sticking to plain HTML, CSS, and JS.

I created Morph while optimizing the development of Telegram Web Apps using Deno and Deno Deploy. Traditional stacks that separate frontend and backend with complex APIs and use React or Vue felt overly heavy, complex, and expensive for small projects.

Currently, Morph runs on Hono, but support for other backends may be added in the future.

  • Each component can call its own API that returns hypertext (other components)\
  • All components are rendered on the server and have access to server-side context\
  • Components can be rendered and re-rendered independently\
  • Components form a hierarchy, can be nested in one another, and returned from APIs\
  • Minimal or no client-side JavaScript\
  • No build step\
  • No need to design API data structures upfront\
  • The library can be embedded into any Deno/Node/Bun project\

Morph is ideal when there’s no need to split frontend and backend into separate services. It works especially well for small Telegram bots, desktop apps, or internal tools that don’t justify a full frontend stack but still need a clean and dynamic UI.

Deno
deno add jsr:@vseplet/morph jsr:@hono/hono

Bun
bunx jsr add @vseplet/morph
bun add hono

Node
npx jsr add @vseplet/morph
npm i --save hono @hono/node-server

Make main.ts and add imports

Deno

import { Hono } from "@hono/hono";
import { component, fn, html, meta, morph, styled } from "@vseplet/morph";

Bun

import { Hono } from "hono";
import { component, fn, html, meta, morph, styled } from "@vseplet/morph";

Node

import { serve } from '@hono/node-server'
import { Hono } from "hono";
import { component, fn, html, meta, morph, styled } from "@vseplet/morph";

Create simple page (for all runtimes)

const app = new Hono()
  .all("/*", async (c) =>
    await morph
      .page("/", component(async () => html`
          ${meta({ title: "Hello, World!" })}

          <h1>Hello, World!</h1>

          <pre class="${styled`color:red;`}">${
            (await (await fetch("https://icanhazdadjoke.com/", {
              headers: {
                Accept: "application/json",
                "User-Agent": "My Fun App (https://example.com)",
              },
            })).json()).joke
          }</pre>

          ${fn(() => alert("Hello!"))}
        `),
      )
    .fetch(c.req.raw));

Deno

Bun

Node

Deno
deno -A main.ts

Bun
bun main.ts

Node
node --experimental-strip-types main.ts

MIT

联系我们 contact @ memedata.com