Hyperspan Templates

Pure JavaScript Streaming Templates used in Hyperspan

      // Template syntax
      // Values can be any scalar value, Promise, nested template, or object with a 'render' method
      function getContent() {
        const content = html`

Some static content here first

${sleep(600, (resolve) => resolve("Resolves second"))}

A bit more static content here as well

${Promise.resolve( html`Resolves first... (Nested: ${sleep(800, (resolve) => resolve(html`Resolves third`))})` )}


${new AsyncValue()}
`; const layout = html`
Layout Header
${content}
`; return layout; }
  // Template syntax
  // Values can be any scalar value, Promise, nested template, or object with a 'render' method
  function getContent() {
    const content = html`

Some static content here first

${sleep(600, (resolve) => resolve("Resolves second"))}

A bit more static content here as well

${Promise.resolve( html`Resolves first... (Nested: ${sleep(800, (resolve) => resolve(html`Resolves third`))})` )}


${new AsyncValue()}
`; const layout = html`
Layout Header
${content}
`; return layout; }

  // Template syntax
  // Values can be any scalar value, Promise, nested template, or object with a 'render' method
  function getContent() {
    const content = html`<div>
      <p>Some static content here first</p>
      <p>${sleep(600, (resolve) => resolve("Resolves second"))}</p>
      <p>A bit more static content here as well</p>
      <p>
        ${Promise.resolve(
          html`Resolves first... (Nested: ${sleep(800, (resolve) => resolve(html`Resolves third`))})`
        )}
      </p>
      <hr />
      ${new CustomObjectWithRenderMethod()}
    </div>`;
  
    return content;
  }
    

These templates...

  1. Are pure JavaScript. No compile step required.
  2. Are extrememly lightweight. Source code with types is less than 300 lines.
  3. Instantly separate static content from async content.
  4. Can render static template content immediately, with placeholders for async content with render.
  5. Can resolve async content out of order and then render it into the correct placeholders when it resolves.
  6. Run all async work in the same template concurrently, not one by one or blocking.
  7. Support unlimited levels of nested templates and nested async content.
  8. Can stream render with renderStream (returns AsyncGenerator)
  9. Can wait for all async work to finish before rendering with renderAsync (returns string)
  10. Work in all JavaScript runtimes that support Template Literals and AsyncGenerator (all major browsers & Node.js, Deno, Bun, Workers, Edge, etc.).

👈 click to view rendering demo

renderStream(tmpl):

Renders immediately. Async content streams in as it resolves. Feels faster.

 

await renderAsync(tmpl):

Waits to render any content untill all async content is resolved. Useful for SEO & bots.