[▲ Vercel Community](/) · [Categories](/categories) · [Latest](/latest) · [Top](/top) · [Live](/live)

[Showcase](/c/showcase/41)

# Building Null MDX: the first v0 Template with real MDX support

45 views · 3 likes · 1 post


Aaron (@ussaaron) · 2026-02-14 · ♥ 3

![null-mdx-hero|690x385](upload://f2BSHPAGnZP011Xjjfz3uqeeeWY.jpeg)

**Introduction**

When Vercel shipped the new v0 in early 2026, they didn't just polish the interface, they rebuilt the entire runtime. The new v0 runs sandbox-based Linux VMs with full Node.js environments. For most people, that meant better code generation. For me, it meant a question: can we finally build a documentation template that compiles real markdown inside v0?

The answer is Null MDX.

**The Problem with Docs Templates**

Every documentation template I tried in v0 had the same limitation: no real MDX support. Content was hardcoded in JSX, stored as JSON, or rendered with basic markdown parsers that couldn't handle components, syntax highlighting, or the plugin ecosystem that makes MDX powerful.

The reason was simple: the old v0 runtime couldn't run compilers. MDX compilation requires next-mdx-remote (or a similar compiler), Shiki or Prism for syntax highlighting, and remark/rehype plugins for processing. These are Node.js packages that need a real runtime to execute.

**How the New v0 VM Makes It Possible**

The new v0 is fundamentally different. As Vercel described in their announcement, the new sandbox-based runtime can "import any GitHub repo and automatically pull environment variables and configurations." Every prompt generates production-ready code in a real environment.

This means v0's sandbox runs an actual Node.js process. It installs dependencies. It executes build tools. It runs compilers. And critically for Null MDX, it compiles .mdx files server-side using the full next-mdx-remote pipeline:

1. **MDX Compilation**: next-mdx-remote reads .mdx files from the content directory and compiles them to React components at request time
2. **Syntax Highlighting**: Shiki processes code blocks with full language grammars, producing accurate, theme-aware highlighted code
3. **Plugin Pipeline**: remark-gfm enables GitHub Flavored Markdown (tables, strikethrough, autolinks), rehype-pretty-code handles code block formatting, and rehype-slug/rehype-autolink-headings generate navigable anchor links
4. **Custom Components**: MDX components like Callout, Steps, and Tabs are mapped to React components and rendered server-side

All of this runs live inside v0. You can open the template, edit an .mdx file, and see compiled, syntax-highlighted, component-rich documentation render in the preview pane.

**What Null MDX Includes**

Null MDX is a production-ready Next.js 16 template designed for content-heavy sites. Here's what ships out of the box:

- **Dual-Mode Architecture**: Toggle between `docs` mode (sidebar navigation, ordered sections) and `blog` mode (chronological posts, author attribution, tags) with a single config change in `lib/site-config.tsx`.

- **Full-Text Search**: A built-in search system with keyboard shortcut support (Cmd+K) that indexes all content at build time.

- **Table of Contents**: Auto-generated from headings with real-time scroll tracking, so readers always know where they are in long documents.

- **Reading Progress**: A visual progress indicator for long-form content.

- **RSS Feed**: Auto-generated at `/blog/feed.xml` for syndication.

- **LLMs.txt**: An AI-friendly content index at `/docs/llms.txt`, making your documentation discoverable by AI agents and language models.

- **Design System Viewer**: A built-in design system page at `/design` that showcases all available components.

**Optional Supabase Asset Management (Inspired by Lee Robinson at Cursor)**

One of the features I'm most proud of is the optional Supabase Storage integration. The inspiration came directly from Lee Robinson's blog post about migrating [cursor.com](https://cursor.com) off its CMS ([leerob.com/agents](https://leerob.com/agents)).

In that post, Lee describes how Cursor was spending $56,848 on CMS CDN usage after just a few months. The fix was straightforward: host assets in object storage and build a simple GUI for managing them. As Lee put it: "This took only 3 or 4 prompts with the agent to get something decent and workable."

Null MDX ships with exactly that pattern, pre-built. Here's what the Supabase integration provides:

1. **Asset API** (`/api/null-mdx/assets`): A full CRUD API for Supabase Storage. Upload files via multipart form data, list assets sorted by creation date, delete by path. Timestamped filenames prevent collisions. Files are cached with `Cache-Control: max-age=31536000` (1 year, immutable).

2. **Individual Asset Serving** (`/api/null-mdx/assets/[name]`): A proxy route that downloads files from Supabase Storage and serves them with proper MIME types. Supports images (JPEG, PNG, GIF, WebP, SVG), PDFs, and video (MP4, WebM). Responses are marked `immutable` for aggressive CDN caching.

3. **Optimized Image Rendering**: The `getOptimizedImageUrl` utility generates Supabase's image transformation URLs with configurable width and quality parameters. Blog cards and MDX image components use this automatically - meaning every image in your content is optimized without manual intervention.

4. **Asset Manager UI** (`/assets`): A full drag-and-drop upload interface with grid view, one-click URL copying, and deletion. This is the "simple GUI on top of object storage" that Lee described building for Cursor.

5. **Graceful Fallback**: The entire Supabase layer is optional. If `NEXT_PUBLIC_SUPABASE_URL` is not set, all image helpers fall back to serving from the local `/images/` directory. The template works identically either way - Supabase just gives you cloud storage and optimization when you need it.

The key insight from Lee's post applies perfectly here: the cost of the CMS abstraction is rarely worth it for developer-focused content sites. Your content is already code (MDX files in a git repo). Your assets should be in simple, cheap object storage. And the GUI for managing them should be something you can build in a few prompts - or in Null MDX's case, something that ships out of the box.

**Multi-Zone Architecture with Null Proxy**

Null MDX is designed to be one half of a complete system. The companion template, Null Proxy, serves as a Multi-Zone gateway that routes requests from a single domain to multiple Next.js applications.

Here's the architecture:

```
User Browser
|
    v
Null Proxy (Landing Page + Router)
|
    |-- /           -> Local landing page
    |-- /docs/*     -> Null MDX (Documentation)
    |-- /blog/*     -> Null MDX (Blog)
    |-- /about      -> Null MDX (About)
    v
Null MDX (Content Engine)
```

This means you deploy Null MDX as your content engine, deploy Null Proxy as your public-facing gateway, and users see a single, unified domain. The proxy handles all routing transparently via Next.js rewrites, and static assets are served correctly through the `assetPrefix` configuration.

Why two repositories? Separation of concerns. Your marketing landing page and your documentation content can be owned by different teams, deployed independently, and scaled separately. Update your docs without touching the landing page. Redesign the landing page without rebuilding the docs.

**The "Null" Philosophy**

The name reflects the design philosophy: start from nothing, with zero assumptions. No opinionated styling to fight against. No bloated features to rip out. Just a clean, minimal foundation that scales with your needs.

Every piece of Null MDX is intentional. The styling uses Tailwind CSS v4 and shadcn/ui, so you get a modern component library without lock-in. The content structure uses standard .mdx files in a `content/` directory, so there's no proprietary format. The configuration is a single TypeScript file, so there's no hidden complexity.

**Getting Started**

You can fork either template directly from v0:

- **Null MDX**: [v0.app/templates/null-mdx-OSVvIj4RBu8](https://v0.app/templates/null-mdx-OSVvIj4RBu8)
- **Null Proxy**: [v0.app/templates/null-proxy-4PQrDpMpnP5](https://v0.app/templates/null-proxy-4PQrDpMpnP5)

Or clone from GitHub:

- **Null MDX**: [github.com/headline-design/null-mdx](https://github.com/headline-design/null-mdx)
- **Null Proxy**: [github.com/headline-design/null-proxy](https://github.com/headline-design/null-proxy)

Live demos:

- **Null MDX**: [null-mdx.vercel.app](https://null-mdx.vercel.app)
- **Null Proxy**: [null-proxy.vercel.app](https://null-proxy.vercel.app)

Both templates are MIT licensed and built for the v0 community.

**What's Next**

This is just the beginning of the Null ecosystem. The combination of v0's new VM capabilities and Next.js Multi-Zones opens up patterns that weren't possible before. Imagine a suite of templates - each responsible for a different concern - all composable under a single domain through Null Proxy.

Documentation, blog, changelog, API reference, marketing site. Each built independently. Each deployable independently. All unified through one routing layer.

Start from nothing. Build everything.

---