No build
One <script src> from a CDN. Open the file from disk. That is the whole toolchain.
SvenJS 3
A tiny UI runtime you drop on a page. No Node, no Vite, no compiler. Tagged templates instead of JSX — save the file and double-click it.
You have clicked 0 times.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>SvenJS</title>
<style>body{font:16px/1.5 system-ui,sans-serif;margin:1.25rem;background:#141210;color:#f2ebe3}
button{font:inherit;cursor:pointer;background:#e07a3d;color:#fff;border:0;border-radius:8px;padding:.55rem .95rem}
input[type=text]{font:inherit;background:#1c1915;border:1px solid #3a342c;border-radius:8px;padding:.5rem .7rem;color:inherit}
.demo-card,.todo-app{max-width:32rem}
h1{font-size:1.6rem;margin:0 0 .8rem}
.todo-list{list-style:none;margin:1rem 0;padding:0}
.todo-list li{display:flex;gap:.6rem;align-items:center;padding:.5rem 0;border-bottom:1px solid #3a342c}
.todo-list li.done label{opacity:.6;text-decoration:line-through}
.destroy{margin-left:auto;background:transparent;color:#a3988c}
.compose-grid{display:grid;gap:.75rem}</style>
</head>
<body>
<div id="app"></div>
<script src="https://unpkg.com/svenjs@3"></script>
<script>
const { create, render, html } = Svenjs;
const App = create({
initialState: { clicks: 0 },
render() {
return html`
<div class="demo-card">
<h1>The Click App</h1>
<button onClick=${() => this.setState({ clicks: this.state.clicks + 1 })}>
Why not click me?
</button>
<p>You have clicked ${this.state.clicks} times.</p>
</div>
`;
},
});
render(App, document.getElementById("app"));
</script>
</body>
</html>
One <script src> from a CDN. Open the file from disk. That is the whole toolchain.
setState replaces the object. Copy the fields you keep. Accidental mutation throws in development.
Tweak the example, hit Download .html, mail the file to yourself. It still runs.
Demos