Partial Hydration
Made Simple
A zero-dependency web component for Islands Architecture. Keep your pages fast and add interactivity exactly where you need it.
export function HelloWorld() {
return (
<!-- Yup, Tailwind is built in -->
<div className="w-full h-full flex items-center justify-center bg-black rounded-lg">
<p className="py-4 px-6 text-4xl text-white">Hello, World!</p>
</div>
);
}
const counterScript = html`
<script type="module">
import canvasConfetti from "https://cdn.jsdelivr.net/npm/canvas-confetti@1.9.3/+esm";
let count = 0;
window.increment = () => {
count++;
const counterElement = document.getElementById("counter-count");
if (counterElement) {
counterElement.textContent = count.toString();
}
if (count === 3) {
canvasConfetti({ particleCount: 100, colors: ["#cdac26", "#d0d0d1", "#292929", "#1b791f"], spread: 70, origin: { y: 0.6 } });
}
};
</script>
`;
export function Counter() {
return (
<sapling-island loading="visible">
<template dangerouslySetInnerHTML={{ __html: counterScript.toString() }}></template>
<div className="w-full h-full flex items-center justify-center">
<button
id="counter-button"
onclick="window.increment?.()"
className="px-6 py-3 bg-gray-900 dark:bg-white text-white dark:text-gray-900 font-medium rounded-full hover:bg-gray-800 dark:hover:bg-gray-100 transition duration-150 flex items-center gap-2">
Click Count: <span id="counter-count">0</span>
</button>
</div>
</sapling-island>
);
}
const motionScript = html`
<script type="module">
import { animate } from "https://cdn.jsdelivr.net/npm/motion@latest/+esm";
animate(
".motion-box",
{ rotate: 90 },
{ type: "spring", repeat: Infinity, repeatDelay: 0.2 }
);
</script>
`;
export function MotionExample() {
return (
<sapling-island loading="visible">
<template dangerouslySetInnerHTML={{ __html: motionScript.toString() }}></template>
<div className="w-full h-full flex items-center justify-center">
<div className="motion-box w-[100px] h-[100px] bg-foreground rounded-lg"></div>
</div>
</sapling-island>
);
}
Hello, World!
A simple tool for building
modern websites
If you know HTML, CSS, Tailwind, and JavaScript, you can build a website with Sapling.
SEO & Performance First
Sapling is built for speed. Using web development best practices for SEO and performance.
Zero JavaScript by Default
Sapling doesn't output any javascript out of the box. Just good old HTML and CSS.


Islands Architecture
Add interactivity only where you need it. Keep the rest of your site fast and lightweight.
Basic by Design #usetheplatform
Build with JavaScript, TypeScript, HTML, and CSS. We don't tie you to any specific framework or bundler which means you can use what you want.
Frequently Asked Questions
Sapling is a zero-dependency, framework-agnostic web component (<sapling-island>) that allows you to progressively hydrate parts of your page. It helps you keep most of your page as static HTML, loading JavaScript and styles only when specific conditions are met.
Sapling isn't a full framework—it's a tool that works with the stack you already have. If you're building traditional server-rendered websites but want the interactivity of modern frameworks without the bloated JS bundles, Sapling lets you easily implement Islands Architecture anywhere.
Yes! Sapling is completely framework-agnostic. You can use it within JSX, React, Vanilla HTML, or any templating language. It simply acts as a boundary to tell the browser when and how to load the interactive bits of your UI.
Sapling supports several loading strategies via the `loading` attribute. You can load scripts immediately (`load`), when the element scrolls into view (`visible`), when the main thread is idle (`idle`), based on media queries (`(min-width: 768px)`), or after a specific timeout.