/isum

isomorphic uhtml

Primary LanguageJavaScript

isum

isomorphic µhtml

Tiny wrapper that imports uhtml in the browser and uhtml/ssr in Node.js/Bun for quick & easy client and server-side rendering (SSR/SSG). With a few extra niceties.

All credits to Andrea Giammarchi for creating this mighty lib.

Example project using isum: ANSI.tools

The Main Idea™

  • Plain and web standards-based JS library, i.e. not a (meta) framework
  • Use render and html to render template literals
  • Optional: use fine-grained reactivity with isum/preactive

Use the provided document of isum and Vite (or something else that builds/bundles) and get SSG for free.

Import the same from isum/preactive for fine-grained reactivity:

import { document, render, signal } from 'isum/preactive';

const count = signal(0);

function App {
  return () => html`<button onclick=${() => count.value++}>Clicks: ${count.value}</button>`;
}

function renderApp() {
  render(document.getElementById("app"), App());
}

This runs in both browsers and runtimes like Node.js.

Please refer to the µhtml docs for details.

Setup

Bootstrap in index.js:

import { renderApp } from './app.js';

renderApp();

Initial template/container index.html:

<!doctype html>
<html>
  <head>
    <link rel="stylesheet" href="styles.css" />
  </head>
  <body>
    <main id="app"></main>
    <script type="module" src="index.js"></script>
  </body>
</html>

SSG

Read template, render application, write result:

import { readFileSync, writeFileSync } from 'node:fs';
import initSSR from 'isum'; // must import same as in rest of app (e.g. 'isum/preactive')
import { renderApp } from './app.js';

const pages = {
  'index.html': () => renderApp()
};

for (const [filePath, render] of Object.entries(pages)) {
  const template = readFileSync(filePath, 'utf-8');
  const { document } = initSSR(template);
  render();
  writeFileSync(filePath, document.toString());
}

This renders the <button> inside <main> into index.html.

Look ma, no bundler!

Run the app in the browser without a build step:

<!doctype html>
<html>
  <head>
    <link rel="stylesheet" href="styles.css" />
    <script type="importmap">
      {
        "imports": {
          "isum": "https://unpkg.com/isum@1.1.0",
          "uhtml": "https://unpkg.com/uhtml@4.7.1/keyed.js"
        }
      }
    </script>
  </head>
  <body>
    <main id="app"></main>
    <script type="module" src="index.js"></script>
  </body>
</html>

CSS imports?

Ignore CSS imports in JS modules during SSG:

node --import isum/no-css build.js

Useful when using e.g. Vite. isum pairs great with Vite.

Examples