11# @amamo/mdx
22
3- Compile trusted MDX into JavaScript modules for a configurable JSX runtime (React by default),
4- collection metadata, and JSON manifests. A Rust native binding handles parsing, validation, media
5- rewriting, manifest projection, and persistent cache records; Shiki runs in JavaScript and feeds
6- highlighted HAST back into the same compile pipeline.
3+ Build MDX collections for Vite 8, Next 16, or a custom Node.js build. Define each collection with
4+ the package's ` z ` schema builder, then import MDX as application modules or consume the generated
5+ collection registry and JSON manifests.
76
8- The package exposes three import paths :
7+ ` @amamo/mdx ` provides :
98
10- | Import | Purpose |
11- | ----------------- | -------------------------------------------------- |
12- | ` @amamo/mdx ` | Configure and drive the compiler directly. |
13- | ` @amamo/mdx/vite ` | Compile MDX through Vite 8. |
14- | ` @amamo/mdx/next ` | Compile MDX for Next 16 with Turbopack or Webpack. |
9+ - frontmatter validation and defaults;
10+ - JavaScript modules for a configurable JSX runtime, with React as the default;
11+ - fenced-code highlighting and Markdown media imports;
12+ - collection metadata with companion TypeScript declarations;
13+ - configurable JSON manifests and a persistent build cache.
1514
16- ## Quick start
15+ ## Requirements
16+
17+ - Node.js 20.19 or newer.
18+ - A [ supported native target] ( https://jikkai.github.io/mdx/native-targets/ ) . There is no JavaScript
19+ or WASI fallback for MDX compilation.
20+ - React 19 when using the default JSX runtime.
21+
22+ MDX can contain imports, expressions, and JSX. Compile content from authors who are allowed to add
23+ application code.
24+
25+ ## Install
1726
1827``` sh
1928pnpm add @amamo/mdx
2029```
2130
22- ` @amamo/mdx ` requires Node.js 20.19 or newer and a [ supported native
23- target] ( https://jikkai.github.io/mdx/native-targets/ ) . It has no JavaScript or WASI fallback.
31+ The package manager installs the platform package for the current operating system and CPU. Install
32+ dependencies again after moving the project to a different platform instead of copying
33+ ` node_modules ` .
34+
35+ ## Define a collection
2436
25- Create a serializable config:
37+ Create ` amamo. config.mjs ` :
2638
2739``` js
28- // amamo.config.mjs
29- import { defineConfig } from ' @amamo/mdx'
40+ import { defineConfig , z } from ' @amamo/mdx'
3041
3142export default defineConfig ({
3243 root: import .meta.dirname,
3344 collections: {
3445 posts: {
3546 directory: ' content/posts' ,
36- schema: {
37- $schema: ' https://json-schema.org/draft/2020-12/schema' ,
38- type: ' object' ,
39- properties: { title: { type: ' string' } },
40- required: [' title' ],
41- },
47+ schema: z .object ({
48+ title: z .string (),
49+ publishedAt: z .string ().optional (),
50+ }),
4251 },
4352 },
4453})
4554```
4655
47- Then choose the integration that owns the build.
56+ Then add ` content/posts/hello.mdx ` :
57+
58+ ``` mdx
59+ ---
60+ title: Hello
61+ publishedAt: 2026-08-15
62+ ---
63+
64+ # Hello
65+
66+ This document is compiled by @amamo/mdx .
67+ ```
68+
69+ The collection directory must exist before the first full build. Relative collection, cache,
70+ generated, and manifest paths are resolved from ` root ` .
71+
72+ ## Choose an integration
4873
4974### Vite
5075
@@ -55,7 +80,9 @@ import { defineConfig } from 'vite'
5580
5681import amamo from ' ./amamo.config.mjs'
5782
58- export default defineConfig ({ plugins: [amamoMdx (amamo )] })
83+ export default defineConfig ({
84+ plugins: [amamoMdx (amamo )],
85+ })
5986```
6087
6188### Next
@@ -66,17 +93,21 @@ import { withAmamoMdx } from '@amamo/mdx/next'
6693
6794import amamo from ' ./amamo.config.mjs'
6895
69- export default withAmamoMdx (amamo )({ reactStrictMode: true })
96+ export default withAmamoMdx (amamo )({
97+ reactStrictMode: true ,
98+ })
7099```
71100
72101### Direct compiler API
73102
74- ``` ts
103+ ``` js
104+ // build-content.mjs
75105import { createCompiler } from ' @amamo/mdx'
76106
77107import amamo from ' ./amamo.config.mjs'
78108
79109const compiler = await createCompiler (amamo)
110+
80111try {
81112 const result = await compiler .build ()
82113 console .log (result)
@@ -85,26 +116,57 @@ try {
85116}
86117```
87118
88- The first build writes these compiler-owned files under ` generatedDirectory ` (default
89- ` .amamo-mdx ` ):
119+ Run the script with ` node build-content.mjs ` .
90120
91- - ` collections.mjs ` — collection metadata with lazy imports of the source MDX files.
92- - ` collections.d.ts ` — a companion declaration output for the collection registry.
93- - ` index.json ` — the private index used by the Next loader.
121+ ## Use compiled content
94122
95- Cache and manifest paths are configured separately and are resolved from ` root ` .
123+ With the Vite plugin or Next wrapper configured, import an MDX file like an application module:
96124
97- ## Security boundary
125+ ``` tsx
126+ import Post , { frontmatter } from ' ./content/posts/hello.mdx'
98127
99- MDX modules can execute JavaScript when the host imports or renders them. Compile only content from
100- trusted authors; schema validation is not a sandbox. Frontmatter fields are ordinary data and may
101- appear in compiled modules, cache records, and configured manifests. Store protected values in an
102- encrypted form and decrypt them in the consumer, or keep them outside frontmatter. See the
103- [ security model] ( https://jikkai.github.io/mdx/security/ ) before handling protected data.
128+ export function Page() {
129+ return (
130+ <main >
131+ <h1 >{ frontmatter .title } </h1 >
132+ <Post />
133+ </main >
134+ )
135+ }
136+ ```
104137
105- ## Documentation
138+ Or load a document from the generated registry:
139+
140+ ``` ts
141+ import { collections } from ' ./.amamo-mdx/collections.mjs'
142+
143+ const hello = collections .posts .find ((document ) => document .slug === ' hello' )
144+ const module = await hello ?.load ()
145+ ```
146+
147+ Registry ` load() ` functions import the source MDX file, so they must run through the configured Vite
148+ plugin or Next loader.
106149
107- The complete English and Simplified Chinese documentation covers:
150+ ## Generated files
151+
152+ The first build writes these files under ` generatedDirectory ` , which defaults to ` .amamo-mdx ` :
153+
154+ - ` collections.mjs ` — sorted collection metadata and lazy source imports;
155+ - ` collections.d.ts ` — TypeScript declarations for the registry;
156+ - ` index.json ` — the source-to-cache index used by the Next loader.
157+
158+ Cache and manifest paths are configured separately from ` generatedDirectory ` . Add ` .amamo-mdx/ ` to
159+ the host repository's ignore file unless the application deliberately tracks generated output.
160+
161+ ## Package entry points
162+
163+ | Import | Use it for |
164+ | ----------------- | ------------------------------------------ |
165+ | ` @amamo/mdx ` | Configuration and the direct compiler API. |
166+ | ` @amamo/mdx/vite ` | Vite 8 development and production builds. |
167+ | ` @amamo/mdx/next ` | Next 16 development and production builds. |
168+
169+ ## Documentation
108170
109171- [ Getting started] ( https://jikkai.github.io/mdx/getting-started/ )
110172- [ Configuration reference] ( https://jikkai.github.io/mdx/configuration/ )
0 commit comments