v0.2.0

Write websites with
Plain English

SEHTML only has one HTML attribute — do="..." that can replace vanilla JS and wires up the click handler, the fetch call, the animation, whatever you asked for. No build step to try it. No JS to write for a toggle button.

Get started View source →
try it!
<button do="when clicked, toggle #hero-panel">
Quick Explanation

Why I built this??

I had to write alot of vanilla JS repeatedly for even simple things like a button, showing/hiding panels, anims, etc... Eventually that got old...

So instead of just dealing with it, I wrote THIS! It reads a sentence out of a do attribute. Things like when clicked, toggle #panel — and does the wiring itself! Adds the event listener, resolves the target element, runs the action. That's the whole idea. It's not trying to replace the big ones like htmx, react, etc... Mainly because it can't but it here to make your days better with less strain!

live mode

Just one <script> tag and every do attribute on the page becomes active. Good for prototypes, static pages, etc.

compiled mode

Run npx sehtml build index.html and it compiles every instruction to plain JS


the vocabulary

What it understands... Hmmm

Each of these is a real, working do="" phrase. copy any line straight into an attribute.

visibility
toggle #panel

Also show and hide. Works on this, an #id, or a .class.

animation
fade in #modal

Fade, slide, grow, shrink — chain them with then for a sequence.

classes
add class 'active' to #tab

State management without touching classList yourself.

network
fetch '/api' show result in #list

GET or POST, with an optional loading bar and result target.

validation
if value is a valid email show #ok

Length, format, ranges, custom regex. checked on input, no library.

persistence
save this as 'draft'

Backed by localStorage. Load it back with load 'draft' into #field.

navigation
scroll to #pricing

Plus go to, open in a new tab, refresh page.

counters
count up #views to 5000 over 2 seconds

Eased number animation. Good for the stat you're proud of.

reordering
when items are reordered, save the new order as 'ranking'

Native drag-and-drop, saved automatically.


Fully functional

Try it yourself

Every demo below is running the actual SEHTML runtime.

01

Debounced email validation

when typed in after 300ms,
  if value is a valid email show #validate-ok
  otherwise hide #validate-ok
02

Count-up, triggered on scroll

when scrolled into view,
  count up #counter to 1000 over 3 seconds
0
lines of JS this page didn't need to write
03

Copy to clipboard

when clicked, copy #copy-target to clipboard
  then show #copy-toast for 2 seconds then hide #copy-toast
04

Saved across reloads

when typed in, save this as 'note'
when this loads, load 'note' into this
Reload this page and whatever you typed will still be there.

side by side comparison

A toggle button, two ways

Same behavior. This is the actual line count.

Vanilla JSSEHTML
const btn = document.querySelector('#btn'); const panel = document.querySelector('#panel'); btn.addEventListener('click', () => { if (panel.style.display === 'none') { panel.style.display = ''; } else { panel.style.display = 'none'; } }); <button do="when clicked, toggle #panel">
9 lines, 2 queries, 1 listener, 1 conditional 1 attribute

FAQs

FAQ

These toggle open the same way everything else on this page works — do="when clicked, toggle #x".

Does this replace JavaScript entirely? +
Is it production ready? +
How's this different from HTMX? +
Can I chain actions? +
What happens if SEHTML can't parse an instruction? +

three steps, no config

Get started

1

Add the runtime — either via npm, or a plain script tag if you don't want a build step.

npm install sehtml
# — or, zero build step —
<script src="https://unpkg.com/sehtml/dist-live/sehtml-live.js"></script>
2

Write your first instruction on any element.

<button do="when clicked, toggle #my-panel">Click me</button>
<div id="my-panel" style="display:none">Hello, SEHTML!</div>
3

When you're ready to ship, compile it down to plain JS — no parser in your production bundle.

npx sehtml build index.html --out dist