Playground

Feel the scheduler

One island on this page. Drag the sliders — the hydration plan moves live between static, lazy and eager.

Static is the default. Every hydrate needs a reason.

Thresholds: eager ≥ 0.3 · lazy ≥ 0.05 · below = no JS.

hydration 0.360eager

Ship the fast path by default

Scaffold a project, declare a few weights, and let the build decide what goes on the wire first.

Capabilities

What it does

01

Scheduler

Render priority = business value ÷ CPU cost. High-conversion nodes move up in the HTML source.

02

Islands

Hydrate eager, lazy, or never. A 300 KB chat widget at conversion 0.05 stays static.

03

SEO

Canonical, Open Graph, JSON-LD, sitemap, hreflang — generated at build time.

04

Images

AVIF/WebP/JPEG via sharp. Profiles, srcset validation, remote sources.

05

SSG + adapters

Static by default. Node, Vercel, Cloudflare adapters for SSR/ISR when you need them.

v0.10 · zero-dependency runtime

What loads first is a business decision.

biagiojs orders HTML, hydration and preload from weights you declare — conversion, SEO, interaction, cost. Pages without islands ship zero JavaScript.

npx create-biagiojs my-sitenpm
0 KB JS default/14 KB demo HTML/AVIF · WebP · JPEG/Node · Vercel · Cloudflare

Measured

This page, audited

Google Lighthouse on this site — mobile on throttled 4G, desktop emulated. One island; everything else static HTML.

Mobile: Lighthouse 100 performance, accessibility, best practices, SEO
Mobile100 · 100 · 100 · 100
Desktop: Lighthouse 100 performance, accessibility, best practices, SEO
Desktop100 · 100 · 100 · 100

Lighthouse 13 · July 2026 · biagio.danilosprovieri.com

Syntax

Declare weights, not lifecycles

pages/index.page.biagio
<page title="Home" description="…" />

<component id="hero" seo="1" conversion="0.9">
  <template><h1>Benvenuto</h1></template>
</component>

// conversion 1 → hydrates first · zero JS elsewhere
<component id="cta" conversion="1" interaction="0.85">
  <template><button id="buy">Compra</button></template>
  <script hydrate>
    el.querySelector('#buy').onclick = () => buy();
  </script>
</component>

Principles

Three ideas, one framework

01

Static is the default

A page ships zero JavaScript until something on it earns hydration. The fast path is the one you don't opt out of.

02

Business weights decide

Conversion, SEO and interaction are inputs to the build, not afterthoughts. The scheduler turns them into source order and a hydration plan.

03

Field data closes the loop

Real CrUX, analytics and heatmap reports recalibrate the weights on every build — the site tunes itself to how people actually use it.

biagiojs