# Carousels > Browser-only tool that turns a pasted numbered X/Twitter thread into a grid of 1080×1080 (or 1080×1350 portrait) carousel images, exportable as individual PNGs, a bulk ZIP, or a multi-page PDF. The tool runs entirely in the browser — parsing, rendering, and export all happen client-side with no backend, no API calls, no tracking beyond anonymous Vercel Analytics. Users paste a numbered thread on the left, the app parses `1/`, `2/`, etc. markers into individual carousel cards, and renders each as a faithful Twitter/X tweet screenshot on a customizable background canvas. Exported PNGs are pixel-identical to the live preview. ## Key features - Pixel-perfect tweet card rendering (Twitter/X fidelity: avatar, verified badge, names, handle, muted-bell and three-dot icons, tabular numbers, emoji via Twemoji for cross-OS consistency). - Inline markdown support inside tweet bodies: bold, italic, backtick `code` (rendered as an amber pill matching the footer arrows), links, hashtags, @mentions. - Fenced code blocks render as ray.so-style cards with syntax highlighting for rust, go, typescript, python, bash, sql, json, zig, and more. - GitHub-flavored markdown tables render as styled table cards. - Arrow-bullet conversion (`-` or `*` at line start becomes `→`). - Per-card image attachments (stored in IndexedDB, persisted across reloads). - Customizable carousel palette: background color, header/footer text color, footer arrow accent. - Square (1:1, 1080×1080) or portrait (4:5, 1080×1350) aspect ratio, toggleable per thread. - Light / dark UI chrome mode. - Click-to-edit on the focused tweet card (raw contentEditable) — formatted render at rest. - Export formats: single PNG, bulk ZIP of all PNGs, multi-page PDF. - Three tools: Thread carousels, Code carousels (single-language code cards), Table carousels. ## Stack - Vite + React 18 + TypeScript strict mode - Tailwind CSS v4 - html-to-image for PNG rendering - highlight.js for syntax highlighting - Twemoji for emoji normalization - jszip + file-saver for bulk export - jsPDF for PDF export - IndexedDB for blob persistence; localStorage for text state - @vercel/analytics + @vercel/speed-insights for privacy-respecting metrics ## Non-goals - No backend, no auth, no database, no server-rendered content. - Not a thread composer. Write the thread elsewhere and paste it in. - Not a general-purpose design tool. The visual system is fixed (no theme/font/color pickers for the *carousel itself* beyond the documented palette variables). ## Author Built by [@goodylili](https://x.com/goodylili) — backend engineer, writer at goodylili.com. ## FAQ **Is it free?** Yes. No sign-up, no account, no paywall. **Does it send my data anywhere?** No. Parsing, rendering, and exporting all happen client-side. Thread text, uploaded images, and exported files never leave the browser. **What can I export?** Individual PNGs, a bulk ZIP of all cards, or a single multi-page PDF. **What dimensions are supported?** Square (1080×1080) and Portrait (1080×1350). **What languages do code blocks support?** Rust, Go, TypeScript, JavaScript, Python, Bash/Shell, SQL, JSON, Zig, and more (via highlight.js). ## Links - Live: https://carousels.goodylili.com - Source: https://github.com/goodylili/carousels - Author site: https://goodylili.com - Author X: https://x.com/goodylili