Fusuma: Write Markdown, Get Slides, PDFs, and a Self-Made Social Card Maneshwar, a developer building git-lrc, discovered that the Markdown-to-slides tool fusuma generates social preview cards by launching a headless Chrome via Puppeteer and taking a real screenshot of the first slide. The tool, created by hiroppy, allows users to write slides in plain Markdown with directives in HTML comments, and outputs static HTML, PDFs, or deploys to GitHub Pages. Maneshwar explored the source code after noticing the CLI mentioned generating og:images. Hello, I'm Maneshwar. I'm building git-lrc, a Micro AI code reviewer that runs on every commit. It is free and source-available on Github. Star git-lrc to help devs discover the project. Do give it a try and share your feedback. A fusuma 襖 , if you didn't grow up around one, is the sliding door in a traditional Japanese house. No hinges, no swinging into someone's face, you just slide it and the room becomes a different room. So when hiroppy named his Markdown-to-slides tool fusuma , the pun was already built into the product: you write one flat file, and sliding between sections turns it into a presentation. I see what you did there, and I respect it. I hadn't used fusuma before this week. I installed it, scaffolded a real project, wrote actual slides explaining fusuma using fusuma, ran the build pipeline, and then went spelunking through node modules because the CLI output during build said something that made me stop and go "wait, it's doing what ." We'll get to that. First, the basics. You install it, run one command, and you have a deck: npm install fusuma -D npx fusuma init That scaffolds a slides/ folder, a style.css , and a .fusumarc.yml config. Your actual content lives in plain Markdown, and every --- on its own line starts a new slide. That's the entire authoring model. No slide objects, no proprietary file format, no clicking "insert text box" forty times. php < -- classes: title -- Hello😃 --- < -- section-title: Bye👋 -- Bye👋 That HTML-comment syntax above Hello😃 isn't decoration, it's a directive fusuma's parser reads to apply a .title CSS class to that slide, and section-title sets what shows up in the sidebar navigation. It's a clever trick: keep the file valid, renderable Markdown for anyone viewing it on GitHub, while smuggling presentation metadata through comments a plain Markdown renderer just ignores. Here's that exact idea rendered for real, from a four-slide deck I built using fusuma to explain fusuma, running the pop theme: Once you're happy with the content, npx fusuma start gets you a dev server on :8080 that hot reloads on every save, no full page refresh, no build step in the way of your edit loop: bash $ npx fusuma start fusuma Compiled successfully fusuma Server running at http://localhost:8080/ Then, when you're actually done, the same file turns into whatever you need next: npx fusuma build optimized static HTML/JS bundle npx fusuma pdf the deck as a single PDF npx fusuma deploy pushes build/ straight to GitHub Pages One Markdown source, sliding into whichever output you need. There's the pun again. I promise I'll ease up. Every screenshot above came out of that same real project, not a mockup: a four-slide deck slides/0-slide.md that explains fusuma using fusuma, with the built-in pop theme enabled through one CSS import, @import '@fusuma/client/assets/style/themes/pop.css'; . That's the entire theming API. The code blocks you see highlighted are running through Prism via @fusuma/prism-loader , and the whole thing is bundled with webpack 5 underneath. Here's what actually made me open the source. I ran npx fusuma build in a folder that had no git remote configured, and got this: - Fetching the remote origin url... build The remote origin url of this repo isn't found. build If you want to generate og:image, please set fusumarc.meta.url Fine, minor warning, no big deal. But "generate og:image" made me curious about how it generates that image, because most tools either template it with a canvas library or just skip it. So I went digging in packages/fusuma/src/server/dynamicRenderingServer.js , and it turns out fusuma doesn't template the social preview card. It launches an actual headless Chrome via Puppeteer, points it at your freshly built deck on a throwaway local server, and takes a real screenshot of your real first slide to use as the og:image . Then, using that same open browser tab, it runs pa11y https://github.com/pa11y/pa11y not Lighthouse, despite what you'd guess against the live page for an accessibility audit, filtering out a couple of known-noisy rules and anything inside a