zaduma is an Astro starter template for understated personal websites, pairing SolidJS, MDX, Tailwind CSS, and Vercel OG to power a minimal blog with dynamic Open Graph images.
What is zaduma?
zaduma is a starter template built with the Astro framework that generates a static blog from MDX posts. It takes posts written in MDX with frontmatter as input and produces a deployable static site with a post index page, individual post pages, and dynamically generated Open Graph images via Vercel OG. The template is available as a GitHub template under the hasparus account.
Key Features
- Astro framework — The site is built with Astro, allowing static generation and CLI commands like
astro addandastro check. - SolidJS integration — Interactive components can be written in SolidJS alongside Astro pages.
- MDX posts — Write posts in MDX (Markdown with JSX), processed through Remark and Unified, enabling interactive content inside Markdown files.
- Shiki Twoslash highlighting — Code blocks are rendered with Shiki Twoslash, which displays type information on hover for TypeScript examples.
- Tailwind CSS styling — Tailwind CSS is configured in
tailwind.config.cjswith custom colors and fonts; global styles live insrc/global-styles/. - Vercel OG dynamic images — Open Graph images are generated on demand for each post through a Vercel OG endpoint protected by an
OG_IMAGE_SECRET. - GitHub Actions deployment — A CI workflow in
workflows/ci.ymlbuilds and deploys to Vercel usingVERCEL_TOKEN,VERCEL_PROJECT_ID, andVERCEL_ORG_IDsecrets. - Playwright tests — The repository includes an
e2edirectory andplaywright.config.tsfor end-to-end testing.
Who is it for?
- Developer-bloggers — People who want a clean, minimal blog where they can write technical posts and showcase code with the added benefit of Twoslash type tooltips.
- Astro users — Those already comfortable with Astro who want a preconfigured project structure with SolidJS and MDX integrated, rather than starting from scratch.
- Design-focused personal site owners — Individuals who prefer an understated aesthetic built with Tailwind CSS and no heavy JavaScript by default.
What can you do with zaduma?
- Publish MDX posts — Drop a
.mdxfile into theposts/directory with frontmatter such asdate, and it automatically appears on the index page and gets a dedicated route via the[path].astrodynamic route. - Generate Open Graph images — Each post gets a dynamically generated social preview image through the Vercel OG integration, secured by an
OG_IMAGE_SECRETyou define. - Deploy with Git history — Using the included GitHub Actions workflow with Vercel secrets, the build can read
git logto derive post dates when they aren't provided in frontmatter.
How does zaduma work?
- Click Use this template on GitHub to create a new repository.
- Install dependencies with
pnpm installand start developing withpnpm run dev(dev server runs atlocalhost:3000). - Write MDX files in
posts/. If a post lacks adate, the template usesexecSync("git log")to infer it. - To deploy, set the three Vercel secrets and
OG_IMAGE_SECRETin GitHub Actions settings. - Remove the
e2edirectory andplaywright.config.tsif you don't need the Playwright tests.
FAQ
Does zaduma require pnpm?
The documented commands in the README use pnpm (such as pnpm install and pnpm run dev), so pnpm is the recommended package manager for this starter.
Can I connect my own Vercel project instead of using GitHub Actions?
Yes. If every post has a date in frontmatter, you can skip the workflow's deploy steps, remove the execSync("git log") call from derivedTitleAndDatePlugin, and connect Vercel or Netlify directly through their integrations.
What is the OG_IMAGE_SECRET used for?
It secures the Vercel OG endpoint that generates Open Graph images. You create a passphrase and store it as a GitHub Actions secret to prevent unauthorized image generation on your public URL.
How do I change the site's fonts and colors?
Global font, body, and prose styles are in src/global-styles/, and Tailwind's theme (colors, fonts) is configured in tailwind.config.cjs. Layout files BaseLayout.astro and PostLayout.astro control the shared page structure.





