---
description: Install @amamo/mdx, define one collection, compile a document, and use the generated output.
---

# Getting started

This guide starts with one `content/posts/hello.mdx` file and ends with a host-importable module,
collection registry, and companion declaration file.

## Requirements

- **Node.js 20.19 or newer.** This is the package's declared engine floor.
- **A supported native target.** The binding has no JavaScript or WASI fallback. See [Native
  targets](/native-targets/).
- **React 19 in the host application.** The default `jsxImportSource` is `react`.
- **Trusted MDX authors.** Compiled MDX can execute JavaScript in the host application.

## Install

<InstallTabs packageName="@amamo/mdx" />

The published root package selects a matching platform package during installation. Do not copy a
`node_modules` directory between operating systems, CPU architectures, or Linux libc variants.

## Add a document

Create the collection directory and a first document:

```mdx
---
title: Hello
---

# Hello

This document is compiled by @amamo/mdx.
```

Save it as `content/posts/hello.mdx`.

## Define the collection

Collection schemas use the package's Zod-compatible `z.object`; every other configuration value
must be plain serializable data. `defineConfig` is an identity helper that exposes the config shape
to TypeScript-aware tooling; schema conversion, validation, and defaults are applied when a compiler
or adapter is created.

```js
// amamo.config.mjs
import { defineConfig, z } from '@amamo/mdx'

export default defineConfig({
  root: import.meta.dirname,
  collections: {
    posts: {
      directory: 'content/posts',
      schema: z.object({ title: z.string() }),
    },
  },
  manifests: {
    public: {
      output: '.amamo-mdx/public.json',
      fields: {
        key: 'key',
        slug: 'slug',
        title: 'title',
      },
    },
  },
})
```

The `content/posts` directory must exist before a full build. Relative collection, cache, generated,
and manifest paths are resolved from `root`.

## Choose who owns the build

### Vite

```ts
// vite.config.ts
import { amamoMdx } from '@amamo/mdx/vite'
import { defineConfig } from 'vite'

import amamo from './amamo.config.mjs'

export default defineConfig({ plugins: [amamoMdx(amamo)] })
```

Vite runs a full startup build, transforms imported content directly, and uses its watcher for add,
change, and unlink events.

### Next

```ts
// next.config.ts
import { withAmamoMdx } from '@amamo/mdx/next'

import amamo from './amamo.config.mjs'

export default withAmamoMdx(amamo)({ reactStrictMode: true })
```

Next builds the persistent cache before development or production bundling, then registers a
read-only loader for Turbopack and Webpack. Keep the cache enabled for this adapter.

### Direct API

```js
// build-content.mjs
import { createCompiler } from '@amamo/mdx'

import amamo from './amamo.config.mjs'

const compiler = await createCompiler(amamo)
try {
  const result = await compiler.build()
  console.log(result)
} finally {
  await compiler.dispose()
}
```

Run it with:

```sh
node build-content.mjs
```

Call `build()` before `transform()` or `remove()` when generated outputs must represent the whole
collection. The incremental methods update the compiler's current in-memory record set; they do not
discover missing siblings by themselves.

## Import content

Inside a configured Vite or Next application, import an MDX file like a module:

```tsx
import Post, { frontmatter } from './content/posts/hello.mdx'

export function Page() {
  return (
    <main>
      <h1>{frontmatter.title}</h1>
      <Post />
    </main>
  )
}
```

Or import the generated collection registry from application code:

```ts
import { collections } from './.amamo-mdx/collections.mjs'

const hello = collections.posts.find((document) => document.slug === 'hello')
const module = await hello?.load()
```

The `load()` function imports the original MDX path, so it must run through a host that has the Vite
plugin or Next loader configured.

## Generated files

With the config above, the first build writes:

```text
.amamo-mdx/
  cache/
  collections.d.ts
  collections.mjs
  index.json
  public.json
```

- `collections.mjs` contains sorted metadata and lazy imports.
- `collections.d.ts` is emitted as a companion declaration file for the registry.
- `index.json` maps source paths to cache records for the Next loader; Vite does not read it.
- `cache/` contains reusable compiled records, including highlighted output.
- `public.json` is the configured manifest. A different `output` may place a manifest elsewhere.

Add `.amamo-mdx/` to the host repository's ignore file. Unchanged shared files and manifests are not
rewritten.

Next, read [Configuration](/configuration/) for every available option and its default.
