@docubook/core 1.8.2 → 2.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,434 +1,149 @@
1
1
  # @docubook/core
2
2
 
3
- Shared MDX compile pipeline and markdown utilities for DocuBook.
3
+ Shared MDX compile pipeline and markdown utilities for the DocuBook ecosystem.
4
4
 
5
- ## Features
5
+ ## Pipeline
6
6
 
7
- - **Centralized MDX Pipeline** - One shared compile flow for all DocuBook projects
8
- - **Managed Remark/Rehype Plugins** - Core markdown plugins are maintained by DocuBook author
9
- - **Content-First Workflow** - Users can focus on docs content instead of plugin maintenance
10
- - **Utility Helpers** - Frontmatter extraction, TOC extraction, and slug helpers included
11
- - **Consistent Behavior** - Same markdown rendering behavior across apps and templates
12
-
13
- ## Installation
14
-
15
- Node.js ecosystem:
16
-
17
- ```bash
18
- npm install @docubook/core
19
7
  ```
20
-
21
- ```bash
22
- pnpm add @docubook/core
8
+ raw MDX string
9
+ │
10
+ ▼
11
+ ┌─────────────────────────────┐
12
+ │ EXTRACT (extract.ts) │ gray-matter → frontmatter
13
+ │ │ regex line-scan → TOC (headings)
14
+ └──────────┬──────────────────┘
15
+ │ strippedContent
16
+ ▼
17
+ ┌─────────────────────────────┐
18
+ │ COMPILE (compile.ts) │ serialize() → MDX compiled output
19
+ │ │ remark: GFM, expandable, directives
20
+ │ │ rehype: preProcess → mermaid → codeTitles
21
+ │ │ → expandable → prism → slug
22
+ │ │ → autolink-headings → postProcess
23
+ └──────────┬──────────────────┘
24
+ │ compiledSource (string) / React element
25
+ ▼
26
+ SSR HTML + static hydration modules
23
27
  ```
24
28
 
25
- ```bash
26
- yarn add @docubook/core
27
- ```
28
-
29
- Bun (independent runtime/package manager):
29
+ Content comes from the local filesystem/repository — there is no runtime
30
+ remote compilation (no database/CMS fetching), so compilation is a pure
31
+ build-time/transform step: `serialize()` turns MDX into a string
32
+ (`function-body` for `<MDXRemote>`, `program` for static hydration modules).
30
33
 
31
- ```bash
32
- bun add @docubook/core
33
- ```
34
+ ## Markdown directives
34
35
 
35
- ## Usage
36
+ The default remark chain parses markdown directives (via `remark-directive`)
37
+ and converts them to MDX components (`remarkDirectiveToMdx`) — so interactive
38
+ components can be authored with markdown-native syntax instead of JSX tags:
36
39
 
37
- ### Quick Start (Recommended)
40
+ ```md
41
+ :::card{title="Hi" horizontal}
42
+ Content here
43
+ :::
38
44
 
39
- ```ts
40
- import { cache } from "react";
41
- import { createMdxContentService } from "@docubook/core";
42
-
43
- type Frontmatter = {
44
- title: string;
45
- description: string;
46
- image: string;
47
- date: string;
48
- };
49
-
50
- type TocItem = {
51
- level: number;
52
- text: string;
53
- href: string;
54
- };
55
-
56
- const components = {
57
- // your MDX components
58
- };
59
-
60
- const docsService = createMdxContentService<Frontmatter, TocItem>({
61
- parseOptions: { components },
62
- cacheFn: cache,
63
- });
45
+ ::::tabs
46
+ :::tab{title="One"}
47
+ A
48
+ :::
49
+ :::tab{title="Two"}
50
+ B
51
+ :::
52
+ ::::
64
53
 
65
- const doc = await docsService.getCompiledForSlug("getting-started/introduction");
66
- const frontmatter = await docsService.getFrontmatterForSlug("getting-started/introduction");
67
- const tocs = await docsService.getTocsForSlug("getting-started/introduction");
54
+ ::youtube{videoId="abc123"}
68
55
  ```
69
56
 
70
- ### Importable APIs and What They Do
57
+ Directive names are PascalCased to match the components map
58
+ (`:::file-tree` → `FileTree`); bare attributes (`{horizontal}`) become
59
+ boolean props. Nested containers need a longer outer fence (`::::`).
71
60
 
72
- #### Runtime APIs
61
+ ## API
62
+
63
+ ### Runtime functions
73
64
 
74
65
  | Function | Description | Returns |
75
66
  | -------- | ----------- | ------- |
76
- | `parseMdx` | Compile raw MDX string with optional custom parse options | `MdxCompileResult<Frontmatter>` |
77
- | `createMdxContentService` | Create slug-based docs service (`getParsedForSlug`, `getCompiledForSlug`, `getFrontmatterForSlug`, `getTocsForSlug`). Accepts optional `frontmatterEnricher` to inject computed or fallback values after parsing | service object |
78
- | `readMdxFileBySlug` | Read `slug.mdx` or `slug/index.mdx` from docs directory | `ReadMdxFileResult` |
79
- | `parseMdxFile` | Convert raw file result into `frontmatter`, `tocs`, `content`, `filePath` | `ParsedMdxFile<Frontmatter, TocItem>` |
80
- | `compileParsedMdxFile` | Compile parsed MDX while preserving metadata and TOCs | `CompiledMdxFile<Frontmatter, TocItem>` |
81
- | `extractFrontmatter` | Parse frontmatter only from raw markdown/MDX | `Frontmatter` |
67
+ | `serialize` | Compile MDX string to compiled output. `outputFormat: "function-body" \| "program"` | `SerializeResult` |
68
+ | `MDXRemote` | Client-side renderer for pre-compiled `serialize()` output | React component |
69
+ | `extractFrontmatter` | Parse frontmatter only | `Frontmatter` |
82
70
  | `extractFrontmatterWithContent` | Extract frontmatter and stripped content in one pass (avoids double parsing) | `{ frontmatter, strippedContent }` |
83
- | `extractTocsFromRawMdx` | Extract headings for table of contents generation | `TocItem[]` |
71
+ | `extractTocsFromRawMdx` | Extract headings for TOC generation | `TocItem[]` |
84
72
  | `sluggify` | Convert heading text into URL-safe slug | `string` |
85
- | `createDefaultRehypePlugins` | Get default DocuBook rehype plugin stack | `unknown[]` |
86
- | `createDefaultRemarkPlugins` | Get default DocuBook remark plugin stack | `unknown[]` |
87
- | `preProcess` | Add pre-processing behavior for code blocks (advanced) | transformer function |
88
- | `postProcess` | Add post-processing behavior for code blocks (advanced) | transformer function |
89
- | `handleCodeTitles` | Move code title metadata to `<pre>` attributes (advanced) | transformer function |
90
- | `handleCodeExpandableRemark` | Remark plugin that detects `Expandable` meta on code blocks and injects expandable data attributes | transformer function |
91
- | `handleCodeExpandable` | Rehype plugin that propagates expandable metadata from `<code>` to `<pre>` elements | transformer function |
92
- | `rehypeMermaid` | Rehype plugin that transforms ` ```mermaid ` fenced code blocks into `<Mermaid chart="...">` elements | transformer function |
93
- | `serialize` | Re-exported from `@docubook/mdx-remote/serialize` for non-RSC MDX compilation workflows | `MDXRemoteSerializeResult` |
94
- | `MDXRemote` | Re-exported from `@docubook/mdx-remote` for client-side MDX hydration | React component |
95
- | `cn` | Merge class names using `clsx` + `tailwind-merge` | `string` |
96
- | `parseDate` | Parse `dd-MM-yyyy` or ISO 8601 date strings into a Date object | `Date` |
97
- | `stringToDate` | Convert a string or Date value to a Date object | `Date` |
98
- | `formatDate` | Format date to long format (e.g. "Thursday, April 5, 2026") | `string` |
99
- | `formatDate2` | Format date to short format (e.g. "Apr 5, 2026") | `string` |
100
- | `toIsoDateOnly` | Convert date to ISO date-only string (e.g. "2026-04-05") | `string` |
101
-
102
- #### Type Exports
103
-
104
- | Type | Purpose |
105
- | -------------------------------- | ------------------------------------------------------------------------- |
106
- | `MdxCompileResult` | Result shape for compiled MDX content |
107
- | `TocItem` | Heading item structure used by TOC extraction |
108
- | `ParseMdxOptions` | Options for `parseMdx` compile behavior |
109
- | `ReadMdxFileResult` | Return type for `readMdxFileBySlug` |
110
- | `ParsedMdxFile` | Parsed file structure before compile |
111
- | `CompiledMdxFile` | Compiled file structure with metadata and TOC |
112
- | `CreateMdxContentServiceOptions` | Options for creating the content service, including `frontmatterEnricher`, `tocsExtractor`, and `readOptions` |
113
- | `ReadMdxBySlugOptions` | Options for `readMdxFileBySlug` — configure `rootDir` and `docsDir` |
114
-
115
- ### Quick Import Recipes
116
-
117
- #### 1. Compile raw MDX only
73
+ | `createDefaultRehypePlugins` | Default rehype plugin stack | `Pluggable[]` |
74
+ | `createDefaultRemarkPlugins` | Default remark stack (GFM, expandable, directives) | `Pluggable[]` |
75
+ | `remarkDirectiveToMdx` | Convert `:::name{attrs}` directives into MDX component elements | transformer |
76
+ | `preProcess` / `postProcess` | Code-block metadata pre/post processing | transformer |
77
+ | `handleCodeTitles` | Move code title metadata to `<pre>` attributes | transformer |
78
+ | `handleCodeExpandableRemark` / `handleCodeExpandable` | Expandable code block remark/rehype plugins | transformer |
79
+ | `rehypeMermaid` | Transform ` ```mermaid ` fenced blocks into `<Mermaid>` elements | transformer |
80
+ | `cn` | Merge class names (`clsx` + `tailwind-merge`) | `string` |
81
+ | `parseDate` / `stringToDate` | Parse `dd-MM-yyyy` or ISO 8601 into `Date` | `Date` |
82
+ | `formatDate` / `formatDate2` / `toIsoDateOnly` | Date formatting helpers | `string` |
118
83
 
119
- ```ts
120
- import { parseMdx } from "@docubook/core";
121
- ```
122
-
123
- Use this when your source is already in memory and you only need compiled content.
84
+ ### Frontmatter validation (zod)
124
85
 
125
- #### 2. Read frontmatter only
126
-
127
- ```ts
128
- import { extractFrontmatter } from "@docubook/core";
129
- ```
130
-
131
- Use this for metadata pages where full MDX compilation is unnecessary.
132
-
133
- #### 3. Extract frontmatter and content in one pass
86
+ Pass `frontmatterSchema` to `extractFrontmatterWithContent` to validate
87
+ frontmatter right after gray-matter parsing.
134
88
 
135
89
  ```ts
90
+ import { z } from "zod";
136
91
  import { extractFrontmatterWithContent } from "@docubook/core";
137
92
 
138
- const { frontmatter, strippedContent } = extractFrontmatterWithContent<{ title: string }>(raw);
139
- ```
140
-
141
- Use this when you need both frontmatter and the content body without the frontmatter block — avoids parsing the file twice compared to calling `extractFrontmatter` and manually stripping.
142
-
143
- #### 4. Build TOC from raw content
144
-
145
- ```ts
146
- import { extractTocsFromRawMdx } from "@docubook/core";
147
- ```
148
-
149
- Use this when you need heading navigation from markdown/MDX text.
150
-
151
- #### 5. Slug-based docs service (recommended for app integration)
152
-
153
- ```ts
154
- import { createMdxContentService } from "@docubook/core";
155
- ```
156
-
157
- Use this as the default app-level integration for frontmatter, TOC, and compiled docs in one service.
158
-
159
- #### 6. Frontmatter enrichment (date fallback, computed fields)
160
-
161
- ```ts
162
- import { createMdxContentService } from "@docubook/core";
163
-
164
- const docsService = createMdxContentService<Frontmatter, TocItem>({
165
- parseOptions: { components },
166
- cacheFn: cache,
167
- frontmatterEnricher: async (frontmatter, absoluteFilePath) => {
168
- if (!frontmatter.date) {
169
- const { promises: fs } = await import("fs");
170
- const stat = await fs.stat(absoluteFilePath);
171
- return { ...frontmatter, date: stat.mtime };
172
- }
173
- return frontmatter;
174
- },
175
- });
176
- ```
177
-
178
- Use this to inject computed or fallback values into frontmatter after parsing — such as a last-modified date from the filesystem or a git commit timestamp. The enricher receives the already-parsed frontmatter and the absolute path of the MDX file on disk, and runs once per slug before caching.
179
-
180
- #### 7. Custom TOC extraction (`tocsExtractor`)
181
-
182
- ```ts
183
- import { createMdxContentService } from "@docubook/core";
184
-
185
- const docsService = createMdxContentService<Frontmatter, TocItem>({
186
- parseOptions: { components },
187
- cacheFn: cache,
188
- tocsExtractor: (rawMdx) => {
189
- // Custom logic to extract headings — e.g. only h2 and h3
190
- return rawMdx
191
- .split("\n")
192
- .filter((line) => /^#{2,3}\s/.test(line))
193
- .map((line) => {
194
- const level = line.startsWith("###") ? 3 : 2;
195
- const text = line.replace(/^#{2,3}\s+/, "");
196
- return { level, text, href: `#${text.toLowerCase().replace(/\s+/g, "-")}` };
197
- });
198
- },
93
+ const frontmatterSchema = z.object({
94
+ title: z.coerce.string().min(1),
95
+ description: z.coerce.string().default(""),
96
+ image: z.coerce.string().url().optional(),
97
+ date: z.coerce.string().optional(),
199
98
  });
200
- ```
201
-
202
- Use this when the default TOC extraction doesn't match your heading structure or you need to filter/transform headings before rendering.
203
-
204
- #### 8. Custom docs directory (`readOptions`)
205
-
206
- ```ts
207
- import { createMdxContentService } from "@docubook/core";
208
-
209
- const docsService = createMdxContentService<Frontmatter, TocItem>({
210
- parseOptions: { components },
211
- cacheFn: cache,
212
- readOptions: {
213
- rootDir: "/absolute/path/to/project", // defaults to process.cwd()
214
- docsDir: "content", // defaults to "docs"
215
- },
216
- });
217
- ```
218
-
219
- Use this when your MDX files live in a non-standard directory (e.g. `content/` instead of `docs/`) or when the working directory differs from the project root.
220
-
221
- #### 9. Root slug behavior
222
-
223
- When an empty or blank slug is passed to `readMdxFileBySlug` or the content service, it resolves to `"index"` — meaning it reads `docs/index.mdx`:
224
-
225
- ```ts
226
- // These are equivalent:
227
- const doc = await docsService.getCompiledForSlug("");
228
- const doc = await docsService.getCompiledForSlug("index");
229
- // Both read from: docs/index.mdx
230
- ```
231
-
232
- For nested slugs, the resolver tries `docs/{slug}.mdx` first, then falls back to `docs/{slug}/index.mdx`.
233
-
234
- #### 10. Low-level file pipeline (advanced)
235
99
 
236
- ```ts
237
- import {
238
- readMdxFileBySlug,
239
- parseMdxFile,
240
- compileParsedMdxFile,
241
- } from "@docubook/core";
242
- ```
243
-
244
- Use this when you need full control over each pipeline step.
245
-
246
- #### 11. Non-RSC MDX compilation (`serialize` + `MDXRemote`)
247
-
248
- ```ts
249
- import { serialize, MDXRemote } from "@docubook/core";
250
-
251
- const mdxSource = await serialize(rawMdx, { parseFrontmatter: true });
252
- // Then in your component:
253
- <MDXRemote {...mdxSource} components={components} />;
254
- ```
255
-
256
- Use this for Pages Router or non-RSC environments where `compileMDX` (used internally by `parseMdx`) is not available. `serialize` compiles MDX on the server and `MDXRemote` hydrates it on the client.
257
-
258
- #### 12. Mermaid diagram support (`rehypeMermaid`)
259
-
260
- ```ts
261
- import { rehypeMermaid } from "@docubook/core";
262
- ```
263
-
264
- This plugin transforms ` ```mermaid ` fenced code blocks into `<Mermaid chart="...">` elements during MDX compilation. It runs after `preProcess` and before other code transforms, so mermaid blocks are converted before prism or expandable-code plugins process them.
265
-
266
- The plugin is included in `createDefaultRehypePlugins()` by default — no manual registration needed.
267
-
268
- In your MDX files:
269
-
270
- ````md
271
- ```mermaid
272
- graph TD
273
- A[Start] --> B{Decision}
274
- B -->|Yes| C[Process]
275
- B -->|No| D[End]
276
- ```
277
- ````
278
-
279
- This requires the `<Mermaid>` component to be registered in your MDX component map (provided by `@docubook/mdx-content`).
280
-
281
- #### 13. Expandable code blocks (code plugins)
282
-
283
- ```ts
284
- import {
285
- handleCodeExpandableRemark,
286
- handleCodeExpandable,
287
- } from "@docubook/core";
288
- ```
289
-
290
- These plugins enable collapsible/expandable code blocks in MDX. Add `Expandable` to the code block meta:
291
-
292
- ````md
293
- ```ts Expandable
294
- // long code block that will be collapsible
295
- ```
296
- ````
297
-
298
- `handleCodeExpandableRemark` runs during remark phase to inject `data-expandable` attributes. `handleCodeExpandable` runs during rehype phase to propagate those attributes to the rendered `<pre>` element. Both are included in `createDefaultRehypePlugins()` and `createDefaultRemarkPlugins()` by default.
299
-
300
- #### 13. Utility functions (`cn`, date helpers)
301
-
302
- ```ts
303
- import { cn, parseDate, formatDate, formatDate2, toIsoDateOnly } from "@docubook/core";
304
-
305
- // Merge Tailwind classes
306
- const className = cn("px-4 py-2", isActive && "bg-blue-500");
307
-
308
- // Parse dates
309
- const date = parseDate("05-04-2026"); // dd-MM-yyyy
310
- const isoDate = parseDate("2026-04-05"); // ISO 8601
311
-
312
- // Format dates
313
- formatDate("2026-04-05"); // "Saturday, April 5, 2026"
314
- formatDate2("2026-04-05"); // "Apr 5, 2026"
315
- toIsoDateOnly("2026-04-05"); // "2026-04-05"
100
+ const { frontmatter, strippedContent } = extractFrontmatterWithContent(rawMdx, frontmatterSchema);
316
101
  ```
317
102
 
318
- These utilities are also available via the subpath export `@docubook/core/utils`.
319
-
320
- ### Basic Compile Helpers
103
+ YAML coerces unquoted values (`date: 2026-06-10` → Date, `3.5` → number), so use
104
+ `z.coerce.*` for fields that must remain strings.
321
105
 
322
- ```ts
323
- import {
324
- parseMdx,
325
- extractFrontmatter,
326
- extractTocsFromRawMdx,
327
- } from "@docubook/core";
106
+ ### Type exports
328
107
 
329
- const raw = `---\ntitle: Intro\n---\n\n## Hello`;
108
+ | Type | Purpose |
109
+ | ---- | ------- |
110
+ | `TocItem` | Heading item structure |
111
+ | `SerializeOptions` / `SerializeResult` | Options/result of `serialize()` |
112
+ | `MDXRemoteSerializeResult` | Shape accepted by `<MDXRemote>` |
113
+ | `MDXRemoteProps` | Props of the `<MDXRemote>` component |
330
114
 
331
- const frontmatter = extractFrontmatter<{ title: string }>(raw);
332
- const toc = extractTocsFromRawMdx(raw);
333
- const compiled = await parseMdx<{ title: string }>(raw);
334
- ```
115
+ ## Subpath export: `@docubook/core/serialize`
335
116
 
336
- ### File-Based Pipeline (Recommended)
117
+ Standalone MDX compilation (same entry the bundlers use):
337
118
 
338
119
  ```ts
339
- import {
340
- createMdxContentService,
341
- readMdxFileBySlug,
342
- parseMdxFile,
343
- compileParsedMdxFile,
344
- } from "@docubook/core";
345
-
346
- type Frontmatter = {
347
- title: string;
348
- description: string;
349
- image: string;
350
- date: string;
351
- };
352
-
353
- const raw = await readMdxFileBySlug("getting-started/introduction");
354
- const parsed = parseMdxFile<Frontmatter>(raw);
355
- const compiled = await compileParsedMdxFile(parsed, {
356
- components: {
357
- // your mdx components
358
- },
359
- });
360
-
361
- const docsService = createMdxContentService<Frontmatter>({
362
- parseOptions: {
363
- components: {
364
- // your mdx components
365
- },
366
- },
367
- });
368
-
369
- const doc = await docsService.getCompiledForSlug("getting-started/introduction");
120
+ import { serialize } from "@docubook/core/serialize";
370
121
  ```
371
122
 
372
- ## Subpath Exports
373
-
374
- ### `@docubook/core/utils`
123
+ ## Subpath export: `@docubook/core/utils`
375
124
 
376
- A lightweight subpath export containing only the utility functions — no MDX compilation dependencies. Use this when you only need class merging or date helpers without pulling in the full compile pipeline.
125
+ Lightweight — utilities only, no MDX compile dependencies:
377
126
 
378
127
  ```ts
379
128
  import { cn, parseDate, stringToDate, formatDate, formatDate2, toIsoDateOnly } from "@docubook/core/utils";
380
129
  ```
381
130
 
382
- | Function | Description |
383
- | --------------- | ----------------------------------------------------------- |
384
- | `cn` | Merge class names using `clsx` + `tailwind-merge` |
385
- | `parseDate` | Parse `dd-MM-yyyy` or ISO 8601 date strings into a Date |
386
- | `stringToDate` | Convert a string or Date value to a Date object |
387
- | `formatDate` | Format date to long format (e.g. "Thursday, April 5, 2026") |
388
- | `formatDate2` | Format date to short format (e.g. "Apr 5, 2026") |
389
- | `toIsoDateOnly` | Convert date to ISO date-only string (e.g. "2026-04-05") |
390
-
391
- ## Dependency Management Policy
392
-
393
- Dependencies required for markdown processing are managed in this package and updated by the DocuBook author.
394
-
395
- This means app-level users should focus on content and integration. Plugin upgrades, compatibility checks, and pipeline maintenance are handled centrally by DocuBook.
396
-
397
- ### Managed Markdown Dependencies
398
-
399
- - @11ty/gray-matter
400
- - rehype-autolink-headings
401
- - rehype-code-titles
402
- - rehype-prism-plus
403
- - rehype-slug
404
- - remark-gfm
405
- - unist-util-visit
406
-
407
- ### Managed Utility Dependencies
408
-
409
- - clsx — class name composition for the `cn()` utility
410
- - tailwind-merge — intelligent Tailwind class merging for the `cn()` utility
411
- - @docubook/mdx-remote — MDX runtime/compile engine (`serialize`, `MDXRemote`)
412
-
413
- The `remark` and `rehype` plugin stack is intentionally owned by this package to avoid dependency drift across apps.
414
-
415
- ## Why This Matters
416
-
417
- - Consistent behavior across all DocuBook-based projects
418
- - Easier maintenance and safer upgrades
419
- - Less dependency duplication in app-level package.json files
420
- - Faster onboarding for users who only need to write docs
421
-
422
- ## Notes
423
-
424
- `@docubook/core` already includes and manages the MDX runtime/compile dependencies (including `@docubook/mdx-remote`) as part of the package contract.
425
-
426
- In most integrations, users only need to install `@docubook/core` and use the core APIs.
131
+ ## Dependencies
427
132
 
428
- Only import `@docubook/mdx-remote` directly in your app if your app explicitly needs it in app-level code.
133
+ Markdown processing dependencies are managed here and updated by the DocuBook
134
+ author — app-level users should not redeclare them.
429
135
 
430
- For compile pipeline plugins (especially `remark` and `rehype` plugins), rely on this package and avoid re-declaring them at app level unless you have a specific override requirement.
136
+ | Category | Packages |
137
+ | -------- | -------- |
138
+ | Frontmatter | `@11ty/gray-matter` |
139
+ | MDX runtime | `@mdx-js/mdx`, `@mdx-js/react`, `vfile`, `vfile-matter`, `unist-util-remove` |
140
+ | Remark plugins | `remark-gfm`, `remark-directive`, `handleCodeExpandable` (internal) |
141
+ | Rehype plugins | `rehype-autolink-headings`, `rehype-code-titles`, `rehype-prism-plus`, `rehype-slug` (internal code plugins) |
142
+ | AST traversal | `unist-util-visit` |
143
+ | Utilities | `clsx`, `tailwind-merge` |
144
+ | Validation | `zod` |
431
145
 
432
146
  ## License
433
147
 
434
- MIT
148
+ MIT — the files under `src/mdx-compiler/` are MPL-2.0 (derived from
149
+ next-mdx-remote); see `LICENSE-MPL-2.0`.