Skip to content

Limitations

No server-side rendering of component internals

Section titled “No server-side rendering of component internals”

A component’s shadow content is produced by setup() when the element connects, in the browser. alacris has no server renderer, and alacris-go does not add one.

What the server renders is the element, its attributes, and its light-DOM slot children. Between first paint and the module loading, the element is present and empty.

Consequences:

  • Content that must be in the initial HTML (for SEO, for readers with JavaScript disabled, for an email client) has to be slot content, not component internals.
  • There is a flash unless you use alacris.Pending, and a reflow regardless unless you reserve space in your own CSS.

define() always calls attachShadow and renders into it. Serving <template shadowrootmode> would leave the declarative content in place and add the rendered content, so it is not supported.

alacris coerces an attribute using the type of the prop’s default. A Go value of a different shape does not error. It produces something the component did not expect:

define('x-y', { props: { tags: [] } }); // object default: JSON.parse
alacris.E("x-y").Prop("tags", "a,b") // not JSON; the component silently keeps []

JSON.parse failing falls back to the default silently, on the client, where you will not see it. Generated wrappers make this impossible; hand-written Prop calls do not.

Integers past 253−1 cannot cross. The library refuses rather than rounding, but the constraint is real: use strings for large identifiers, and have the component treat them as strings.

Decimal currency has the usual float problem. Send minor units as an integer, or a string, or a struct, not a float64.

Sessions live in the memory of the process that created them:

  • Session affinity is required behind a load balancer.
  • Broadcast reaches one instance’s sessions. Fanning out across instances needs your own bus. See Deploying.
  • SSE is a held connection. Proxies must not buffer it, and your http.Server must not have a WriteTimeout.

Layers one and two have none of these properties.

An element the server intends to patch needs an id, and it has to be unique on the page. There is no selector support: a selector that matches two elements, or none, fails in a way the server cannot see.

An action is a round trip. The page shows the change when the server says so. For a slow network that is visible, and the library does not hide it.

You can do it by hand: have the component update locally and emit, and let the server’s patch confirm or correct it. Nothing coordinates that for you, and reconciling a rejected optimistic update is your problem.

An action is JSON, size-capped. Upload with an ordinary form or fetch, then send an action referring to the result.

What is not supported in alacris templates

Section titled “What is not supported in alacris templates”

These come from the runtime, and matter when writing the JavaScript half:

  • Dynamic tag names: html`<${tag}>` does not work.
  • Bindings inside <textarea> or <title> text: use .value / .textContent.
  • Unquoted partial attributes: write class="a ${b}", not class=a${b}.

Needs <template>, TreeWalker, and (for component styles) adoptedStyleSheets: Chrome/Edge 73+, Safari 16.4+, Firefox 101+. There is a <style> fallback where constructable stylesheets are missing.

The live client needs EventSource and fetch, which is a wider set than the above.

The app module opens the OS webview onto loopback HTTP. That needs CGO and the platform webview: Xcode Command Line Tools on macOS, WebView2 on Windows, libwebkit2gtk on Linux. Cross-compiling CGO is not supported.

The host binds 127.0.0.1, checks Host, and (on Run) requires a host token the webview alone holds. EventSource still needs HTTP, so there is no custom scheme. See Desktop apps.

Native menus and trays are installed on macOS, Windows, and Linux. Dialogs (SaveFile, Message, …) work on all three (zenity or kdialog on Linux).

If you needConsider
Component internals in the initial HTMLA server-rendered template language, or a framework with real SSR
To swap server-rendered HTMLhtmx, Datastar, Turbo
A large client-side app with routing and its own stateA client framework
Interactive islands with SSR and hydrationAstro with a UI framework
Native widgets, not web componentsFyne
JS bindings to Go methods inside a webviewWails

alacris-go is at its best when the server owns the data, the browser owns the interaction, and you would rather write Go than a client-side state layer.