Looking back This describes the 2025 Bunki build. The site now uses Astro; the code and tooling choices below document that earlier implementation.
Claude Code got this blog from an architecture plan to a working deployment for $10. Syntax highlighting took several attempts, timezone handling needed custom filters, and I still ended up with code I could understand and change.
Part 1 covers how I got started and chose the architecture. This part covers the implementation and deployment.
Markdown Processing
parser.ts reads files with fs-extra, extracts frontmatter with gray-matter, converts markdown to HTML with marked, and sanitizes the output against XSS while preserving syntax highlighting.
The key decision is to register only the languages you need, which keeps memory low.
// Register only the languages needed
hljs.registerLanguage("javascript", javascript);
hljs.registerLanguage("typescript", typescript);
hljs.registerLanguage("markdown", markdown);
hljs.registerLanguage("python", python);
hljs.registerLanguage("json", json);
// Configure marked with syntax highlighting
const marked = new Marked(
markedHighlight({
emptyLangClass: "hljs",
langPrefix: "hljs language-",
highlight(code, lang, info) {
const language = hljs.getLanguage(lang) ? lang : "json";
return hljs.highlight(code, { language }).value;
},
}),
);
Claude also added automatic external link handling and excerpt generation.
Static Site Generation
generator.ts orchestrates the build: reads markdown from the content directory, generates tag pages, renders Nunjucks templates to HTML, compiles SCSS to CSS with theme variables, and creates RSS feeds and sitemaps.
Templating
The Nunjucks setup includes a base template for shared HTML structure, separate templates for index, post, and tag pages, custom date filters for Pacific timezone formatting, and SCSS compilation with theme variables from config.
Where Claude Struggled
Software engineering with an AI assistant is not frictionless.
Syntax highlighting took several rounds. Claude’s first attempt at configuring highlight.js didn’t work. After back-and-forth, we landed on language-specific imports that performed well.
External links went smoothly. Claude added target="_blank" and security attributes to external links automatically.
Timezone handling needed custom Nunjucks filters for consistent Pacific timezone dates.
Build and Deploy
The build commands in CLAUDE.md:
- Build: `npm run build`
- Development: `npm run dev`
- Generate static site: `npm run generate`
- Serve site: `npm run serve`
- Deploy to Cloudflare: `npm run deploy`
I used Claude to research Cloudflare Pages deployment, then deployed with wrangler.
What I Learned
Claude thinks through full-stack projects architecturally. Watching it plan the generator taught me more about static site internals than building one from tutorials would have. Structuring a modular TypeScript project and wiring up Cloudflare Pages deployment — I now understand both well enough to modify them without AI help.
Running /init also gave Claude a project guide it could reuse instead of rediscovering the same commands.
The Result
The total cost was $10 for a working blog built with TypeScript, Nunjucks, and SCSS. SEO, accessibility, and security were all generated through conversation. The result was not perfect, but it was a real starting point I could own and modify.
That first generator did not remain frozen. I later moved its build from Node to Bun and its hosting from Pages to Workers. The useful result was not that Claude produced a permanent architecture. It gave me a codebase I understood well enough to keep changing. My current division of work is in Claude Code: what I actually use.
Was this useful?
Thanks for the feedback.