◆ シンプルなものだと同じコードで動く
◆ 互換性ない部分もあるけど頑張ればどっちでも動かせるものが作れそう

似たように書けるなぁと思っていましたが エクスポートされる関数名も一緒だったので同じコードで動きました

<!doctype html>
<meta charset="utf-8" />

<style>
.red { color: red; }
.blue { color: blue; }
.green { color: green; }
</style>

<script type="module">
import { html, render } from "https://unpkg.com/lit-html"

const colors = ["red", "blue", "green"]

render(
html`
<h1>lit-html rendering</h1>
<p>${"abc".repeat(5)}</p>
<div>${
colors.map(e => html`<div class=${e}>${e}</div>`)
}</div>
`,
document.getElementById("lit-html-root")
)
</script>

<script type="module">
import { html, render } from "https://unpkg.com/htm/preact/standalone.module.js"

const colors = ["red", "blue", "green"]

render(
html`
<h1>htm-preact rendering</h1>
<p>${"abc".repeat(5)}</p>
<div>${
colors.map(e => html`<div class=${e}>${e}</div>`)
}</div>
`,
document.getElementById("htm-preact-root")
)
</script>

<div id="lit-html-root"></div>
<div id="htm-preact-root"></div>

上側が lit-html で下側が htm+preact です
違いは h1 の中のテキストとコンテナになる HTMLElement の id だけです

関数にまとめてしまってこれでも動きます

<!doctype html>
<meta charset="utf-8" />

<style>
.red { color: red; }
.blue { color: blue; }
.green { color: green; }
</style>

<script type="module">
import * as lithtml from "https://unpkg.com/lit-html"
import * as htmpreact from "https://unpkg.com/htm/preact/standalone.module.js"

const commonRender = (name, lib, container) => {
const { html, render } = lib
const colors = ["red", "blue", "green"]

render(
html`
<h1>${name} rendering</h1>
<p>${"abc".repeat(5)}</p>
<div>${
colors.map(e => html`<div class=${e}>${e}</div>`)
}</div>
`,
container
)
}

commonRender("lit-html", lithtml, document.getElementById("lit-html-root"))
commonRender("htm-preact", htmpreact, document.getElementById("htm-preact-root"))
</script>

<div id="lit-html-root"></div>
<div id="htm-preact-root"></div>

違い

シンプルなものだと同じコードでいいのですが 完全に一緒とはいかないです
すでに見つけたものだけでもこれだけ違いがありました

属性名

lit-html では @ や . など記号を使ってプロパティやイベントリスナなどを表します
htm では (P)React の createElement の第 2 引数で指定するものに合わせないといけません
hyperhtml のほうが近くなると思います

XML

htm は JSX と同じで XML で書かないといけません
input みたいな終了タグなしで self closing でもないタグは HTML だと許可されてますが XML だと不正です
こういうのがあるとエラーになるかおかしな構造として扱われてしまいます

lit-html では HTML としてブラウザがパースするので HTML であれば問題なしです

タグ名

lit-html ではタグ名の部分に ${} を使うことはできません
タグ全体を条件分岐で出し分けることになります

htm の場合は (P)React で createElement の第 1 引数にコンポーネントを指定するように動的なものを設定できます
その場合の閉じタグは <//> です

エスケープ

HTML ではテキストとして HTML タグを書きたい場合は &lt;div&gt; のようにエスケープします
lit-html ではこれは有効ですが htm の場合はアンエスケープされず そのまま &lt; などがテキストとして表示されます

回避方法は ${} を使って文字列として HTML タグを入れることです

html`<h1>${"<div>"}</h1>`

まとめ

htm はまだ使って数日なので 他にもまだ違いは色々あるかもしれません
見つけた限りだと互換性はけっこう高めです

XML やエスケープのものは htm の書き方は lit-html でも有効なので この辺は htm で動く書き方してれば lit-html でも動きます
(P)React 風な使い方をすればコンポーネントを作るので タグ名に ${} を使うことになりますが lit-html のような使い方にしてコンポーネントを作らないならタグ名に ${} を使うことはほぼ無いです
属性名のところだけが難しいですが htm の bind のところでフックして lit-html の属性名を (P)React の属性名に置換するような処理を入れれば完全互換も夢じゃないかもしれません

そこまでして両方で動くコードを書くメリットはたぶん無いですけどね