My personal blog. Posts are markdown files; the site is a small React + Vite app deployed to GitHub Pages.
Create a markdown file in src/posts/:
---
title: My Post Title
date: 2026-06-09
description: One sentence shown in the post list and RSS feed.
tags: comma, separated, topics
---
Post body in markdown.The filename becomes the URL slug (src/posts/my-post.md → /posts/my-post).
Commit and push to main — GitHub Actions builds and deploys automatically.
To offer a post in Spanish, add my-post.es.md next to it with translated
frontmatter and body (the date comes from the English file). The EN/ES
toggle in the header switches between them; posts without a translation stay
in English.
Create a markdown file in src/oss/:
---
repo: obra/superpowers
added: 2026-08-01
topic: ai
---
One or two sentences on why you keep coming back to it.topic is optional. Topics listed in TOPIC_ORDER in src/lib/oss.js float to
the top of the section in that order; everything else follows. Within each
group entries sort by added, newest first.
The repo name, owner, avatar, language, star count and license are fetched from
GitHub by scripts/fetch-repos.mjs during the build and written to
src/data/repos.json, which is committed. If the fetch fails the last known
values are reused, so a rate limit or an outage never breaks the build. Spanish
translations work like posts: add superpowers.es.md beside it.
npm install
npm run dev # local dev server
npm test # run tests
npm run build # production build + RSS feed + 404 fallbacksrc/lib/posts.jsloads every markdown file insrc/posts/at build time viaimport.meta.globand parses the frontmatter.scripts/generate-rss.mjswritesdist/rss.xmlfrom the same files after each build.dist/404.htmlis a copy ofindex.htmlso GitHub Pages serves the SPA for direct links to/posts/....- Dark mode defaults to the system preference; the header toggle overrides it and persists the choice in localStorage.
- Deployment is handled by
.github/workflows/deploy.ymlon every push tomain.