Install & Compatibility
Where this runs
tested against v0.7.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.95 runs
installs and imports cleanly · install 0.0s · import 0.226s · 19.6MB
glibcpy 3.10–3.95 runs
installs and imports cleanly · install 1.8s · import 0.204s · 20MB
18MB installed
● package 18MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
HTML
✓ from htmltools import HTML
TagList
✓ from htmltools import TagList
Tag
✓ from htmltools import Tag
✗ from htmltools.tags import div
While `Tag` exists, it's generally recommended to use the tag functions from `htmltools.tags` (e.g., `tags.div()`, `tags.a()`) for convenience rather than instantiating `Tag` directly.
tags
✓ from htmltools import tags
`tags` is an object that provides convenient access to common HTML tag functions (e.g., `tags.div`, `tags.p`).
HTMLDependency
✓ from htmltools import HTMLDependency
Used for bundling CSS and JavaScript resources.
css
✓ from htmltools import css
A helper function for generating CSS style declarations.
This quickstart demonstrates creating a hierarchical HTML structure using `tags` functions, applying CSS styles with `css()`, defining an `HTMLDependency` for external assets, and rendering the combined output to a string using `TagList().get_html_string()`.
from htmltools import HTML, TagList, tags, HTMLDependency, css
# Create a simple HTML tag
my_div = tags.div(
tags.h1('Hello, htmltools!'),
tags.p('This is a paragraph generated programmatically.'),
tags.a('Learn more', href='https://github.com/rstudio/py-htmltools'),
_class='container',
style=css(background_color='lightblue', padding='15px')
)
# Create an HTML dependency (e.g., for a CSS file)
my_dependency = HTMLDependency(
name='my-custom-css',
version='1.0.0',
source={'package': 'my_app', 'subdir': 'assets'},
stylesheet={'href': 'style.css'}
)
# Combine into a TagList and render
output_html = TagList(my_div, my_dependency).get_html_string()
print(output_html)
Debug
Known issues
breaking`HTML` objects no longer inherit directly from `str` and now inherit from `collections.UserString`.fixAvoid treating `HTML` objects as raw strings directly. If string-like operations are needed, access the underlying string via the object's methods or by explicit conversion if `UserString` methods are insufficient. This was done to prevent confusion and unexpected behavior when `HTML` objects were implicitly converted or manipulated as plain strings.
affects: >=0.6.0
breaking`TagList` objects no longer inherit directly from `list` and now inherit from `collections.UserList`.fixAvoid treating `TagList` objects as raw lists directly. Access elements and perform list-like operations using the object's methods (e.g., `append`, `extend`, indexing) rather than relying on direct list inheritance. This change aims to reduce confusion and provide more controlled behavior.
affects: >=0.6.0
breaking`Tag` and `TagList`'s method `.get_html_string()` now returns a plain `str` instead of an `HTML` object.fixIf you previously expected the return value of `.get_html_string()` to be an `HTML` object (e.g., for further `HTML` object-specific methods), you might need to re-wrap the result in `HTML()` explicitly, although in most rendering contexts, a standard `str` should be sufficient.
affects: >=0.6.0
gotchaThe `css()` function translates Python keyword arguments into CSS property names. It automatically converts `_` (underscore) and `camelCase` to `kebab-case`.fixWhen using `css()`, prefer Pythonic names like `background_color` or `backgroundColor`; the function will correctly convert them to `background-color` in the output CSS. This is a convenience feature, but can be confusing if not expected.
affects: All versions
gotchaThe default value for the `_add_ws` parameter in `Tag` functions changed for inline vs. block elements in version 0.2.0.fixBy default, block elements like `div()` now have `_add_ws=True` (add whitespace), while inline elements like `span()` have `_add_ws=False` (no whitespace). If precise control over whitespace between sibling elements is critical, explicitly set `_add_ws=True` or `_add_ws=False` on `Tag` function calls.
affects: >=0.2.0 (change from older behavior)
Errors
Common errors & fixes
TypeError: 'HTML' object cannot be interpreted as a string literal
In `htmltools` version 0.6.0, `HTML` objects no longer inherit directly from `str` but from `collections.UserString`. This means functions expecting a raw string literal may raise a TypeError when passed an `HTML` object directly.
fixExplicitly convert the `HTML` object to a string using `str()` if a raw string is required, or ensure the receiving function can handle `UserString` or objects with a `__str__` method. For example: `str(html_object)`.
TypeError: 'TagList' object is not a list
With `htmltools` version 0.6.0, `TagList` objects no longer inherit directly from `list` but from `collections.UserList`. Code that assumes direct list inheritance (e.g., using list-specific methods or operations without calling `TagList` methods) may encounter a TypeError.
fixAccess elements and perform list-like operations using the `TagList` object's methods (e.g., `append`, `extend`, indexing) or treat it as a `collections.UserList`. If a raw list is needed, convert it explicitly (e.g., `list(tag_list_object)`).
ModuleNotFoundError: name 'div' is not defined
Developers often try to import HTML tag functions like `div`, `p`, or `span` directly from the top-level `htmltools` module, but these are located within the `htmltools.tags` submodule.
fixImport the specific tag functions from `htmltools.tags` or use the `tags` object directly. Example: `from htmltools.tags import div` or `from htmltools import tags; tags.div()`.
Upgrade
Version history
0.7.0latest on PyPI · released May 21, 2026
Audit
Dependencies
typing-extensionsrequiredRequired for type hints and compatibility.
packagingrequiredUsed for version parsing and comparison.