@admirable-oss/mdx-press
| Install | |
|---|---|
npm install @admirable-oss/mdx-press |
|
| Latest Version: | 0.0.1 |
| Vue: | 3 |
| Last Updated: | Sep 10, 2026 |
| Links: | npm |
MDXPress
A native Rspack/Rsbuild plugin that compiles .mdx files directly into Vue components, with blazing-fast native performance and built-in dev-server HMR — edit a .mdx file and see your changes update instantly, just like any other component in your project.
Built for and used by admirable-oss/kyc's design-system app (apps/identity), and published as its own package because the problem it solves — content-authored-separately-from-code that still hot-reloads — isn't specific to that app.
Why this exists
The obvious tool for "MDX in a bundler" is unplugin-vue-markdown or @mdx-js/loader. Both were tried here first and didn't work with Rsbuild's Vue toolchain (rspack-vue-loader, a different implementation than webpack's vue-loader) — a separately-registered rspack plugin injecting its own module rule has no ordering guarantee against @rsbuild/plugin-vue's own rule for the same file, so the markdown transform silently never ran.
mdx-press takes a narrower, more direct approach: one loader, chained into the same module rule as rspack-vue-loader, with a documented, deterministic execution order. No unplugin abstraction layer, no separate plugin registration to race against.
What you get
.mdxfiles compile to real Vue components — nov-html, no runtime markdown parsing in the browser.- Each compiled component has two static named exports:
headings(an{ id, level, text }[]outline of itsh2/h3s) andfrontmatter(its---YAML block, flat string fields only). - Real HMR, inherited from
rspack-vue-loaderitself — not a custom dev-server hack. - One runtime dependency tree:
markdown-it+markdown-it-anchor. No MDX/JSX compiler, no Babel.
Install
pnpm add @admirable-oss/mdx-press
Requires @rsbuild/plugin-vue to already be configured in your project — mdx-press relies on the VueLoaderPlugin it registers and doesn't register a second one.
Setup
// rsbuild.config.ts
import { pluginMdxPress } from "@admirable-oss/mdx-press";
import { defineConfig } from "@rsbuild/core";
import { pluginVue } from "@rsbuild/plugin-vue";
export default defineConfig({
plugins: [
pluginVue(),
pluginMdxPress({
// Optional: Tailwind (or any) utility classes injected onto generated
// tags — there's no Vue template to put class= on markdown-generated
// HTML, so this is how you theme it.
classes: {
h2: "text-2xl font-bold",
h3: "text-lg font-semibold",
paragraph: "leading-relaxed",
list: "list-disc pl-5",
inlineCode: "rounded bg-gray-100 px-1.5 py-0.5 font-mono",
},
}),
],
});
Add the ambient module declaration so TypeScript knows what importing a .mdx file gives you:
// tsconfig.json
{
"compilerOptions": {
"types": ["@admirable-oss/mdx-press/client"]
}
}
Usage
Write content in .mdx — plain markdown, plus raw HTML for anything that needs a visual treatment markdown can't express (styled with the same utility classes as the rest of your app, since it's just HTML):
---
title: Colors
---
## Foundation
### Colors
<div class="grid grid-cols-3 gap-2">
<div class="rounded border p-2"><span class="block h-8 bg-black"></span>Ink</div>
</div>
Import it like any component — headings/frontmatter come along as named exports:
<script setup lang="ts">
import Content, { headings, frontmatter } from "./colors.mdx";
</script>
<template>
<h1>{{ frontmatter.title }}</h1>
<nav>
<a v-for="h in headings" :key="h.id" :href="https://github.com/admirable-oss/kyc/blob/HEAD/`#${h.id}`">{{ h.text }}</a>
</nav>
<Content />
</template>
What this is not
There's no live-Vue-component-embedding inside the markdown itself (the actual "MDX" part of MDX — <MyComponent /> written directly in the .md prose). That's what broke with unplugin-vue-markdown + rspack-vue-loader. If you need a real component inside a content page today, render it in the Vue file that imports the .mdx content, alongside <Content /> — not inside the markdown source.
html: true is on by default in the underlying markdown-it instance — mdx-press assumes first-party-authored content (docs, design-system pages you write yourself), not untrusted/user-submitted markdown. Don't point it at user input.
API
pluginMdxPress(options?)— the Rsbuild plugin.options.test(default/\.mdx$/),options.classes,options.wrapperClass(default"mdx-press", the class on the element wrapping rendered content),options.vueLoaderOptions(forwarded torspack-vue-loader).createMdxParser(classes?)— the underlying markdown-it wrapper, if you want to parse markdown yourself outside the loader (e.g. in a script, in tests).
License
MIT
Related Packages
An Rsbuild plugin for Vue DevTools - feature parity with vite-plugin-vue-devtool...
Storybook for Vue3 and Rsbuild: Develop React Component in isolation with Hot Re...
Version History
| Version | Released | Vue | License |
|---|---|---|---|
| 0.0.1 | ^3.2.0 |