Documentation

Security & Markdown

TinyJS escapes ordinary values, rejects common scripting surfaces, and limits raw HTML to explicit trusted output.

Escaped by default

Values interpolated into TinyJS TSX are escaped by default. Content such as a page title or plain text field is treated as text, not executable HTML.

Rejected scripting surfaces

TinyJS rejects inline event-handler attributes and scripting URL protocols. Inline handler attributes are also absent from TinyJS's JSX type system, so TypeScript catches them before runtime.

Trusted generated HTML

raw() exists for HTML that is already trusted and intentionally generated. It is an explicit boundary: use ordinary interpolated values for untrusted content.

Safe Markdown

The bundled Markdown helper escapes input before producing HTML and filters unsafe link protocols. In a page template:

import type { PageProps } from '@carl.fyi/tinyjs'

export default function Article({ markdown, page }: PageProps) {
  return (
    <article>
      <h1>{page.title}</h1>
      {page.markdown ? markdown(page.markdown) : null}
    </article>
  )
}

The helper uses raw() only after its own escaping and unsafe-protocol filtering. Plain page fields should remain ordinary interpolated values.