shadcn/typeset
A single CSS file that styles HTML elements and rendered markdown. Add one class, everything inside gets styled. No per-element classes needed.
Quick Start
npx shadcn@latest add typeset
<div className="typeset">{markdownContent}</div>
Core Controls (3 CSS custom properties)
| Property | Purpose | Default |
|---|---|---|
--typeset-size |
Base font size | Inherits from container |
--typeset-leading |
Line height multiplier | ~1.6 |
--typeset-flow |
Spacing between block elements | ~1em |
Multiple Contexts
.typeset-chat {
--typeset-leading: 1.6;
--typeset-flow: 1em;
}
.typeset-docs {
--typeset-size: 15px;
--typeset-leading: 1.75;
--typeset-flow: 1.5em;
}
<div className="typeset typeset-chat">{message}</div>
<article className="typeset typeset-docs">{page}</article>
Why This Helps AI Agents
- Single class — agents don't need to add per-element Tailwind classes
- Streaming-safe — new blocks appended during streaming don't restyle earlier ones
- No dependencies — CSS file lives in your project, no package layer
- Theme-aware — uses your existing shadcn theme tokens (colors, fonts)
- Flexible — create as many typesets as you need for different contexts
Use Cases
- Blog posts rendered from MDX/markdown
- Documentation pages
- Chat message content (AI-generated markdown)
- Product descriptions
- Any content where you have raw HTML or markdown that needs consistent typography
Pitfalls
- Typeset only styles semantic HTML elements (h1-h6, p, ul, ol, table, pre, code, etc.)
- If your content has class-based styling already, typeset won't override it
- For streaming, wrap only the content portion, not the entire conversation