OpenElement — Web Standards Lab

A Web Components-native application framework — beautiful, static-first applications composed from real browser primitives.
§1 — Element
Custom Elements are the application component contract — not a renderer integration, not a leaf-widget format. Write the element once; it renders on the server and upgrades in the browser.
import { defineElement } from '@openelement/element'
export const Counter = defineElement('open-counter', {
render: (props) => (
<button type="button">Count: {props.count ?? 0}</button>
),
})
// SSR: <open-counter count="0"> + DSD shadow root.
// No JavaScript required for first paint.§2 — Declarative Shadow DOM
DSD is the default server output. No client re-render, no double payload — the markup is the application.
<open-counter count="0">
<template shadowrootmode="open">
<button>0</button>
</template>└─ <button> → signal bound
first paint = interactive§3 — Islands
Interactive regions hydrate on your schedule. The rest of the page never ships a byte of JavaScript.
Critical interactivity, hydrated immediately after parse.
Upgrades when the browser is idle — never blocks paint.
IntersectionObserver gates hydration until scroll-in.
Client-only, for what the server cannot know.
§4 — Output
§5 — Begin
$deno run -A --minimum-dependency-age 0 npm:@openelement/create my-appThe default dist-tag is stable v0.43.3; --minimum-dependency-age 0 keeps same-day compatible patches installable despite Deno's default ~24h minimumDependencyAge.
Facts behind the feeling
Every scene is grounded in the public product surface, architecture and release truth — not a decorative fiction.