JST ships the template, not a sealed element

Every recipe below is a complete, copyable <script type="jst"> block shown next to its live instances. Open the Show the template source disclosure and the code you see is exactly the code running above it - the custom element falls out of source you can read, copy into your page, and edit. Nothing is hidden behind Shadow DOM.

These recipes live in the examples, deliberately not shipped in jst-components.html: the library stays lean and you own your copy. Want half-star precision gone, a different glyph, a byte ladder in binary units? Edit the template. There is no build step and nothing to override from the outside.

green - the platform already does this, no JST needed red - a JST component; the template you see is the implementation purple - JST's CSS-only layout hooks third-party - an external library dropped into a JST component

<jst-rating>

<jst-rating>

Stars driven by a declared value (half steps supported) and a max. It is a keyboard slider: focus it and use the arrow keys, Home, and End. Clicking the left or right half of a star sets a half or whole value. Every change emits a change event up, which the page renders elsewhere. Colour comes from --jst-accent.

event caught by the page: 3 / 5

Restyle it by editing the template: the glyph, the half-star precision and the accent variable are all right here, with no Shadow DOM parts to fight.

Show the template source

<jst-copy-button>

<jst-copy-button>

navigator.clipboard.writeText of the button's value, or the text of the element its target selector points at. It flips to a confirmed state for 1.5 seconds, then flips back, all from the one declared copied attribute.

git clone https://github.com/br3nt/jst
Show the template source

<jst-relative-time>

<jst-relative-time>

The wording is pure Intl.RelativeTimeFormat picking the best unit; JST is the reactive wrapper. once('tick', ...) schedules a timer sized to that unit - seconds re-render every second, minutes every minute - and returns a cleanup that clears it on disconnect. A <time> element carries the absolute value in its datetime and title.

seconds (watch it tick)
minutes
hours
days
future
Show the template source

<jst-format-bytes>

<jst-format-bytes>

A byte count in, a human size out. The number and unit label come from Intl.NumberFormat with its unit style.

0
512
1536
1048576
1073741824
2500000000000

Intl gotcha, why the template uses a manual ladder: asking Intl for notation:'compact' together with unit:'byte' reads cleanly up to the megabyte, but at the gigabyte it collides - the compact scale suffix "B" (billion) lands next to the byte symbol and you get 1.1BB. So the template picks the unit itself (dividing by 1000) and formats with plain, non-compact Intl.NumberFormat, which yields a clean 1.1 GB.

Show the template source

<jst-format-number> & <jst-format-date>

<jst-format-number>

Two thin templates over Intl.NumberFormat and Intl.DateTimeFormat. locale is optional and defaults to the page locale. These are the recipes that show JST's smallest useful shape: declare the inputs, call the platform, escape the output.

currency (USD)
currency (EUR, de)
percent
decimal
unit (km/h)
date (medium)
date + time (long/short)
date (full, fr)
Show both template sources


<markdown-block>

marked 15 + DOMPurify 3

Render user-supplied Markdown to HTML without opening an XSS hole - and the safety pattern is the real lesson. trustedHTML(...) is the one opt-out of JST's automatic escaping, so third-party HTML must be sanitized before it gets there. The pattern, in order: marked turns the source into HTML, DOMPurify strips anything dangerous from that HTML, and only the sanitized result is passed to $(trustedHTML(...)). The source below deliberately includes a <script> tag and a javascript: link; watch them get stripped while the real formatting survives.

If the CDN is unreachable the block renders nothing and says so; the escape hatch never fires without its sanitizer. That is the safe default, and the rest of this page keeps working.

Show the template source

<qr-code>

qrcode-generator 1.4

A pinned QR library draws into a jst-preserve'd mount built once in once('qr', ...). Republishing value re-renders through the stored _render function, exactly like the third-party charts recipe: JST stays a thin controlled-renderer over a preserved node the library owns.

If the CDN is unreachable the mount shows a note and the JST wrapper still renders. Nothing else on the page depends on it.

Show the template source

Takeaway

None of these is a framework feature. A rating, a copy button, a byte formatter: each is a short template that leans on the platform (Intl, the clipboard, custom elements) and, where a real library helps, drops one in behind a preserved mount. JST's job is to stay out of the way and keep the source in your hands. Copy any block above into your own page and change it.