SvenJS 3

SvenJS 3

One HTML file. A button. State. That’s it.

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.

unpkg.com/svenjs@3 · script tag · html`…`

The Click App

You have clicked 0 times.

hello.html — open in a browser, no npm
<!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>

No build

One <script src> from a CDN. Open the file from disk. That is the whole toolchain.

State you can see

setState replaces the object. Copy the fields you keep. Accidental mutation throws in development.

Download from the playground

Tweak the example, hit Download .html, mail the file to yourself. It still runs.

Demos