Embed Raku
One script tag turns code on your page into a real, running Raku editor. It works on any host — a blog, a documentation site, a conference slide deck.
Load the script #
Anywhere in the page. Nothing to install, no build step, no npm.
<script src="https://raku.online/raku.js"></script>
Mark the code #
Any element carrying data-raku becomes editable and runnable.
<pre data-raku>say "Hello from an embedded editor!";</pre>
That markup renders this — go ahead and change it:
say "Hello from an embedded editor!";
For an empty editor to type into instead, use an empty element:
<div data-raku data-run></div>
Already have Raku code blocks? #
Add data-auto to the script tag and every existing
<pre><code class="language-raku"> block on the page becomes
runnable. You change nothing else — this is the shape Markdown, Prism,
highlight.js and the WordPress code block already emit.
<script src="https://raku.online/raku.js" data-auto></script>
If your highlighter uses a different language name, name it:
data-auto="raku perl6".
Options #
All optional. The first three go on the block, the rest on the script tag.
data-run | Run once, as soon as the interpreter is ready. |
data-stdin="…" | Preset standard input, and reveal the input box. |
data-rows="N" | Initial editor height in text rows. Defaults to fitting the code. |
data-theme="dark" | A page-wide default. Otherwise editors follow the host page's theme, live. |
data-selector="…" | Use your own selector instead of [data-raku]. |
data-playground="…" | Where the ↗ button opens the program. Only matters if you host the files yourself. |
Match your colours #
The editor is magenta because raku.online is. Each one lives in its own Shadow DOM, so your stylesheet cannot reach inside it — with one deliberate exception: CSS custom properties do inherit across that boundary, and the widget reads its accent from one. Set it anywhere above the block.
:root { --rk-embed-accent: #0969da; } /* every editor on the page */
Or on a single wrapper, for one editor:
<div style="--rk-embed-accent: #2e7d32">
<pre data-raku>say "a green Run button";</pre>
</div>
Which renders this:
say "a green Run button";
One value covers everything the editor accents: the ▶ Run button's fill, the
■ Stop outline while a program is running, and error text in the output pane.
Nothing else about the widget is themable on purpose — the rest follows the
host page's light/dark setting, which is what
data-theme above overrides.
Host it yourself #
The script tag above loads everything from raku.online. Serving it yourself instead costs you three files and no third-party requests — it works offline, behind a firewall, and stays pinned to the version you copied.
raku.js | The widget — this page's script tag. 32 KB. |
rakujs.js | The WebAssembly loader. 110 KB. |
rakujs.wasm | The interpreter itself. 7 MB, ≈2 MB gzipped, downloaded once and cached. |
raku.js resolves the other two relative to its own URL,
so the one rule is that all three sit in the same directory. Anywhere on your
site will do. Take them straight from here:
mkdir -p your-site/raku && cd your-site/raku
curl -O https://raku.online/raku.js
curl -O https://raku.online/rakujs.js
curl -O https://raku.online/rakujs.wasm
Then point the script tag at your copy. Everything else on this page is unchanged.
<script src="/raku/raku.js"></script>
<pre data-raku>say "Hello from my own server!";</pre>
To pin the engine to a released interpreter instead, every
Raku++ release attaches
rakujs-<tag>.zip — the same rakujs.js and
rakujs.wasm, built by that release's CI:
gh release download -R ash/rakupp --pattern 'rakujs-v*.zip'
The widget raku.js is not in that zip — it belongs to this site;
take it from the URL above.
What your server must do #
- Serve
.wasmasapplication/wasm. Most static hosts already do. Without it the browser cannot stream-compile and falls back to a slower path. - Serve over
http(s). Opening the page as afile://URL will not work — the widget runs your visitors' code in a Web Worker, andfile://cannot start one. - Nothing else. Same-origin files need no CORS headers, and there is no build step, no npm package, and no server-side anything.
Two details #
- Update the three together. They are built, stamped and tested as one set; a new widget against an old
.wasmis not a combination anyone has tried. - The ↗ button on each editor hands the current program to the full playground. From your own copy it opens raku.online; send it somewhere else with
data-playground="https://example.com/play/"on the script tag.
Three things worth knowing #
- One interpreter per page. Ten editors share a single WebAssembly instance — one download, one worker, not ten.
- It cannot break your CSS. Each editor lives in its own Shadow DOM: your styles cannot reach in, and ours cannot leak out.
- Nothing is sent anywhere. Your visitors' code runs in your visitors' browsers. There is no server, so there is nothing for you to run or pay for.
Next #
- The embed builder — set the options, see a live preview, copy the snippet.
- Every pattern, side by side — runnable blocks, stdin, empty editors, auto-enhancement, forced themes.