# What Is Self-Contained HTML? — Single-File Reports and Their Ceiling

Canonical: https://commareports.com/glossary/self-contained-html
Published: 2026-09-11

> Self-contained HTML inlines every stylesheet, script and image into one file so it opens with no sibling directory. How generators produce it, what it costs in size, and where it stops working.

# Self-contained HTML

**A self-contained HTML file inlines every stylesheet, script, font and
image into the document itself — as `<style>` and `<script>` blocks and
[`data:` URIs](/glossary/data-uri) — so it renders correctly with no
sibling directory and no network access.** Also called standalone,
single-file or embedded-resource HTML.

It exists because the default output of most report generators is a
[directory](/glossary/html-report), and directories do not survive being
emailed, dropped into a chat, or attached to a ticket.

## How to produce one

| Tool              | Flag                                             |
| ----------------- | ------------------------------------------------ |
| Pandoc            | `--embed-resources --standalone`                 |
| Jupyter nbconvert | `--to html --embed-images`                       |
| Quarto            | `--embed-resources` (or `embed-resources: true`) |
| Plotly            | `include_plotlyjs="inline"`, `full_html=True`    |
| Bokeh             | `file_html(plot, INLINE)`                        |
| R Markdown        | `self_contained: true` (the default)             |
| Vega / Altair     | `chart.save("x.html", inline=True)`              |

Tools without a flag — Allure, most coverage reporters, Storybook — are
not oversights. Their reports are architecturally multi-file: a shell
that fetches a JSON tree at runtime. Inlining a tree of thousands of
per-test JSON files into one document is not a flag, it is a rewrite.

## The size tax

Base64 encoding inflates binary data by roughly 33%, and inlining
defeats every browser optimisation that made the multi-file version fast:

- Nothing is cached between loads. Every open re-downloads everything.
- Nothing is lazy. Images below the fold parse with the rest.
- The parser blocks on the whole document before first paint.

A report that was a 400 KB entry file plus 6 MB of assets becomes an
8 MB single file that takes seconds to open and will not attach to most
mail servers ([too big to email](/fix/html-file-too-big-to-email)).

## What it fixes, and what it doesn't

**Fixes:** missing CSS, dead scripts, broken images, 404s on
click-through — everything caused by the entry file travelling alone.

**Does not fix:**

- Attachment size limits, which it usually makes worse.
- Chat clients that refuse to preview HTML for security reasons
  ([why Slack won't](/fix/slack-wont-preview-html-file)).
- The reader's `file://` origin, which still blocks any runtime `fetch()`
  the page does ([same-origin policy](/glossary/same-origin-policy)).
- Comments, versions, and knowing whether anyone opened it.

Self-contained HTML solves a packaging problem. Sending someone a file
and hoping remains a delivery problem.

## The alternative to packaging

Publish the directory as it is. Assets upload alongside the entry HTML
with relative references rewritten to the uploaded copies, so nothing
needs inlining, nothing inflates by a third, and the recipient gets a
URL instead of an attachment — one that renders on a phone, in a ticket
preview, and behind a corporate proxy.

**Limits:** entry HTML 5 MB; assets 25 MB per file, 250 MB and 500 files
per report. Single-file exports that exceed 5 MB are almost always
inlined assets, which is the case where uploading the original directory
is both smaller and faster.

## Try it

Comma is free — unlimited reports, unlimited commenters, unlimited
revision history.

**[Publish a report directory →](https://commareports.com/)**

### Related

- [Share an HTML folder](/share-html-folder) · [Host an HTML file](/host-html-file)
- [Data URI](/glossary/data-uri) · [HTML report](/glossary/html-report)
- [The HTML file is too big to email](/fix/html-file-too-big-to-email) · [Glossary](/glossary)
