This Blog
Source, stack, and design decisions behind nikhedonia.dev — a coding and mathematics blog built with Next.js, MDX, and interactive React components.
Motivation
Over two decades of programming and consulting, I've accumulated hundreds of code snippets, notes, and case-studies — half-written proofs, one-file benchmarks, debugging war stories, algorithm implementations that took a weekend to get right. For most of that time they sat on a hard drive, occasionally useful to me but invisible to anyone else.
I don't want them to rot. I want an easy way to make them public so they might help someone else the same way a random blog post once helped me.
The catch: many of those notes are rough — cryptic shorthand, half-finished derivations, code without context. LLMs changed this. It's now fast to take a messy note and produce something readable without losing the original insight. This blog is the result of that process: my accumulated scraps, polished just enough to publish, presented with decent math rendering and interactive visualizations where the math deserves to be felt, not just read.
Most of what ends up here is not novel research. It's things I found non-obvious, things I had to derive myself, or things I wish had been explained differently when I first encountered them.
Technical Stack
The blog is a Next.js App Router application, styled with Tailwind v4, and authored entirely in MDX.
MDX Pipeline
Content lives in content/{articles,slides,projects,snippets}/*.mdx. Each file has YAML frontmatter with title, date, description, banner, and tags.
The MDX pipeline is powered by next-mdx-remote/rsc — React Server Components render the content, so there's no client-side overhead for static prose. Interactive components are loaded with next/dynamic (no SSR) and injected via a central component map.
const Counter = dynamic(() => import('@/components/interactive/Counter'), { ssr: false })
const SineWave = dynamic(() => import('@/components/interactive/SineWave'), { ssr: false })
const FourierViz = dynamic(() => import('@/components/interactive/FourierViz'), { ssr: false })
export const mdxComponents = { Counter, SineWave, FourierViz, Callout, ...htmlOverrides }MDX files can then use <Counter /> or <SineWave /> directly without any imports — the components map handles everything.
Syntax Highlighting
Code blocks use rehype-pretty-code with the Shiki engine and the github-dark theme. This gives VS Code-quality highlighting with zero client-side JavaScript.
```python title="example.py"
def fib(n): return n if n < 2 else fib(n-1) + fib(n-2)
```Mathematics
Math is rendered server-side with KaTeX via remark-math + rehype-katex. Both inline () and display mode are supported:
Content Layout System
Different content types use different layouts:
| Type | Layout | Key Feature |
|---|---|---|
| Articles | Full banner + prose | Long-form, math-heavy |
| Slides | Card-per-slide | Presentation-style |
| Projects | Tech stack + links header | Portfolio display |
| Snippets | Compact, code-first | Quick reference |
Adding New Interactive Components
- Create
components/interactive/MyComponent.tsx(must be a Client Component) - Add a dynamic import to
lib/mdx-components.tsx - Use
<MyComponent />in any MDX file — no per-file imports needed
That's the whole workflow.