Hyperscript is a scripting language for The Web. It is designed to embed well directly in HTML.
Here is a simple example of some hyperscript:
<button _="on click toggle .red on me">
Click Me
</button>
The first thing you probably noticed is that hyperscript is defined directly on the button, using the _ (underscore)
attribute.
This is the hyperscript way: you put the code on the thing that does the thing.
The second thing you probably notices is that hyperscript reads like english. Hyperscript is a member of the xTalk family of scripting languages, starting with HyperTalk.
This syntax has some big advantages for a scripting language for the web:
It takes a bit to get used to, but once you do it is very readable, making behavior obvious.
Hyperscript is dependency-free and can be installed with a simple <script> tag:
<script src="https://cdn.jsdelivr.net/npm/hyperscript.org@0.9.90/dist/_hyperscript.min.js" integrity="sha384-kNli9q2SAIKZyCaj/HsxM+q3rmzWVyOTVcwQ/X1tVf7h38a1wkbfBYpckMRA0eSr" crossorigin="anonymous"></script>
Hyperscript ships as an ES module too, either from the CDN:
<script type="module" src="https://cdn.jsdelivr.net/npm/hyperscript.org@0.9.90/dist/_hyperscript.esm.min.js" integrity="sha384-lNDEj2nrXBoU9smz+Hrc/bS3az2j390bFp8N7GvggJy3MkhIYx1aKrMVbJhuobyK" crossorigin="anonymous"></script>
or via npm.
The npm package is hyperscript.org (yes, the full domain name):
npm install hyperscript.org
Then import it in your bundler of choice:
import 'hyperscript.org';
The import auto-initializes hyperscript on the page, you don't need to import anything.
Once hyperscript is installed, you can add hyperscript scripts to any element using the _ (underscore) attribute:
<button _="on click put 'Hello World' into me">
Click Me!
</button>
You can also place hyperscript in script tags of type text/hyperscript
<script type="text/hyperscript">
on mousedown
log "A mouse down happened: ", event
end
</script>
Hyperscript is a sister project of htmx.
OK, let's learn us some hyperscript...
You might be wondering: how big is this thing?
Hyperscript is ~38KB over the wire (minified + brotli'd). That's the full language: parser, runtime, async engine, event system, everything.
Here's what that means in practice:
| Network | Typical Speed | Latency | Transfer Time | Total |
|---|---|---|---|---|
| 3G | 2 Mbps | ~100ms | ~152ms | ~250ms |
| 4G | 30 Mbps | ~50ms | ~10ms | ~60ms |
| 5G | 100+ Mbps | ~10ms | ~3ms | ~13ms |
On 3G, hyperscript loads in about a quarter of a second. On a modern connection it's effectively instant.
More importantly: this is usually a one-time cost.
With proper Cache-Control headers (which CDNs like jsDelivr set automatically), returning visitors
never download it again. The browser stores both the downloaded file and its compiled bytecode,
so subsequent page loads pay zero network cost and near-zero parse cost across all your pages that use it.
Furthermore, browsers download resources in parallel.
While hyperscript is loading, your images, stylesheets, and other assets are loading too, and only the largest ones matter. A single hero image is typically 200KB–2MB, dwarfing hyperscript's 38KB.
In practice, hyperscript typically finishes downloading long before images, meaning it adds nothing to your overall page load.
So, in most cases, hyperscript is effectively free, hiding for one trip entirely within the download time of assets you were already paying for.