DeltaHtml

Hex.pm VersionHex DocsLicenseGitHub Actions Workflow Status

Server-side renderer for Quill (Slab) Delta: keep Delta as your source of truth in storage, rehydrate Quill for editing, and render HTML for display surfaces (web UI, emails, PDFs).

30-Second Start

# 1) Add dependency
# {:delta_html, "~> 0.5"}

# 2) Convert Quill Delta to HTML
DeltaHtml.to_html([
  %{"insert" => "Hello "},
  %{"attributes" => %{"bold" => true}, "insert" => "world"},
  %{"insert" => "!\n"}
])
# => "<p>Hello <strong>world</strong>!</p>"

What This Is Useful For

Typical production workflow with Quill:

  1. Use Quill in your frontend edit form.
  2. Save only the Delta JSON in your backend/database.
  3. When user edits again, load that Delta back into Quill (rehydrate editor state).
  4. When rendering rich text (web UI, emails, PDFs), convert stored Delta to HTML with DeltaHtml.

This keeps a single source of truth (Delta) while generating HTML only when you need to display content.

Usage

iex> DeltaHtml.to_html([%{"insert" => "word\n"}])
"<p>word</p>"

# With whitespace preservation
iex> DeltaHtml.to_html([%{"insert" => "a   b\tc\n"}], preserve_whitespace: true)
"<div style=\"white-space: pre-wrap;\"><p>a   b\tc\n</p></div>"

Quill CSS Mode

Use quill_css: true to emit Quill-style classes for block attributes:

iex> DeltaHtml.to_html(
...>   [%{"insert" => "x"}, %{"attributes" => %{"align" => "center", "direction" => "rtl", "indent" => 2}, "insert" => "\n"}],
...>   quill_css: true
...> )
"<p class=\"ql-align-center ql-direction-rtl ql-indent-2\">x</p>"

Note: this mode is intentionally not identical to Quill getSemanticHTML() for all attributes. Quill semantic output commonly uses inline styles for align/direction, while quill_css: true prefers classes for easier reuse of Quill theme CSS.

Supported Features

Inline

Block

Plugins

Extensibility

There are currently no extension points for additional formats or plugins. The implementation is a fairly short single file, so copying and adapting it is straightforward.

Alternatives

Quill Parity Harness

The repository includes a JS harness under quill_harness/ that renders Delta with Quill 2 (getSemanticHTML) and feeds parity checks in Elixir tests.

mix quill.setup
mix test

Development Checks

mix precommit

mix precommit runs:

Styler is configured as a formatter plugin and runs through mix format (not as a standalone Mix task).