Render a standalone React component (Tailwind + Recharts + lucide-react) to PNG / SVG / PDF / JPG / WebP via the `poster_render` tool. Use when the user asks for a chart, dashboard, report card, social-share image, OG image, year-in-review, editorial data story, magazine layout, or any visual deliverable that should come out as a single image/document file. Not for interactive UIs; posters are compositions.
Render a standalone React component (Tailwind + Recharts + lucide-react) to PNG / SVG / PDF / JPG / WebP via the `poster_render` tool. Use when the user asks for a chart, dashboard, report card, social-share image, OG image, year-in-review, editorial data story, magazine layout, or any visual deliverable that should come out as a single image/document file. Not for interactive UIs; posters are compositions.
poster
Render a single-file React component to an image. One tool: poster_render.
Write TSX like a graphic designer composes a poster, not like a web developer building a page. Everything is fixed-width, non-responsive, pixel-precise, and optimized to look amazing at thumbnail size on a social feed.
When to reach for poster_render
Chart, dashboard snapshot, OG image, social-share card, year-in-review, editorial data story, magazine layout, event poster, calendar, cover image, PDF one-pager, README hero. Anything that's a composition meant to be looked at, not interacted with.
Not for: interactive UIs, forms, multi-page sites, anything needing runtime JS behavior after render.
The contract
These aren't style preferences — break them and the tool rejects the render.
1. The root element declares the canvas — this is the only source of truth
The tool has no width or height parameter. The root
's Tailwind size IS the canvas. The renderer measures it exactly.
// ✓ width only — height emerges from content (use this 80% of the time)
<div className="w-[1600px] p-10 ...">
// ✓ width + height — fixed aspect for magazine covers, story format, etc.
<div className="w-[1080px] h-[1350px] p-10 ...">
// ✗ rejected — no root width (canvas defaults, usually wrong)
<div className="p-10 ...">
// ✗ rejected — min-h-screen stretches to viewport, not canvas
<div className="w-[1600px] min-h-screen ...">
// ✗ rejected — w-full next to w-[Npx] overrides the explicit width
<div className="w-[1600px] w-full ...">
// ✗ brittle — aspect without explicit width is indeterminate
<div className="aspect-[4/5] p-10 ...">
If you use absolute-positioned decorations (top: 40%, gradient blobs), you need a definite parent height — add h-[Npx] or min-h-[Npx] to the root.
2. Font-size floor: 14px
Anything ≤12px disappears when the poster is viewed at half scale on a feed. Don't go below text-sm (14px) or text-[14px]. Recharts axis ticks: fontSize: 13. Chart-internal SVG labels: fontSize: 13+.
parent has no fixed height — percentage resolves to 0
use pixel math: height: ${(v/max)*80}px
Content at bottom of fixed-aspect poster is missing
content overflows h-[Npx] and root has overflow-hidden
drop h-[Npx] (let height be content-driven), or reduce content
"Muddy" color feel
mixed 3+ accent families
pick one family
"Generic webpage" feel
no kicker/footer rhythm
add small-caps eyebrows + muted footer
Fixed-aspect posters need to budget content to the canvas
When you declare w-[1080px] h-[1350px], any content that extends past 1350px gets clipped (root usually has overflow-hidden to contain gradient blobs). Before writing the TSX, mentally add up section heights:
If the budget is tight, either drop a section or switch to content-driven height (just w-[Npx]). The wrapped example does this — width fixed at 1080, height emerges.
Bar charts / histograms without Recharts
If you're drawing bars by hand (not via Recharts), use pixel math for the bar heights, not percentages:
// ✗ collapses to 0 if parent is content-driven
<div style={{ height: `${(v / max) * 100}%` }} />
// ✓ explicit pixel ceiling, works everywhere<divstyle={{height: `${(v / max) * 80}px` }} />
Or constrain the parent to a fixed pixel height (h-[120px]) and put the bar inside with h-full / absolute positioning.
Calling the tool
poster_render({
tsx: "<your full TSX source as a string>",
out: "./chart.png"
})
That's it. No width or height — the TSX root's Tailwind size is the canvas. Format is inferred from the extension (.png, .svg, .pdf, .jpg, .webp).
The tool returns the resolved absolute path, the rendered pixel dimensions (so you can sanity-check), size in KB, and format. Surface that to the user so they know where the file landed.