stephenkiers.com
2007 - Present
ProfessionalThis is the site you're reading. It's a folder of markdown files and React routes that compile to plain HTML and get served from Cloudflare Pages. There's no server and no CMS. When I want to add something, I write a file and push.
I've had the domain since 2007. It's always been my thing. It was a photography site for a while, and then it was whatever. I'd abandoned it and stopped keeping it up to date.
I built this version in one afternoon, November 24, 2025. I started with Next.js 14 and the App Router, set it up for static export, got a hello world deploying to Cloudflare, then built the real pages: resume, about, a feed. The full site landed as a commit at 12:46. About forty minutes later I ripped Next.js out. The next commit, at 13:28, is "Migrate from Next.js to Vite + TanStack Router." Same afternoon, same pages, different framework underneath.
I just don't like Next.js. I don't like its routing or the paradigm it pushes, and it has too much overhead. I'd rather build something with less vendor lock-in, in plain React. Vite is faster, I'd liked it on other projects, and I wanted to experiment with it more. For routing I just wanted something new. The React Router team had gone off and built a whole other framework, Remix, then folded it back into React Router, and that made me want to try TanStack Router.
What brought the site back was LLMs. They made it practical to pull in all my old articles and repost everything in one place. I want it to be a sales pitch I can point people at, and it's turned into something of an online diary too. The biggest thing is that people who want to know about me have a place to look.
How it works
- Vite, React 18, TypeScript, and Tailwind. TanStack Router does file-based routing, so a page is a file under
src/routes/. - Principles, projects, and the resume are markdown with YAML frontmatter under
content/, pulled in at build time withimport.meta.globand turned into HTML by gray-matter and remark. - Longer articles are a React component each, so a post can have its own layout, callouts, and chat-transcript blocks.
- The build runs
tsc, then Vite, then presite writes every route out as static HTML. Small scripts fix the meta tags, generate the sitemap and RSS feed, and clear the old article URLs so Cloudflare redirects can take over. - Project frontmatter is validated during the build. A missing or malformed field fails the build and names the file.
- Development happens in Docker. Cloudflare Pages redeploys on every push to main.
The older articles here came from Medium, from company blogs, and from earlier versions of stephenkiers.com. I just wanted all my stuff in one place.
What I learned
- A personal site can be a folder of markdown and React routes with no server and no CMS. Adding something is writing a file and pushing.
- Swapping the framework underneath cost about forty minutes on the same afternoon. I started with Next.js, didn't like its routing, its paradigm, or its overhead, and moved to Vite and TanStack Router for less vendor lock-in and plain React.
- LLMs made it practical to pull years of old articles back from Medium and company blogs and repost them in one place. That's what brought the site back.
- Validate content frontmatter in the build. A missing or malformed field fails the build and names the file, so bad content never ships.