{"_id":"@ngrok/remark-mdx-no-paragraph-wrap","_rev":"2-6a90e4d21afa4fbeba753b2c9592691e","name":"@ngrok/remark-mdx-no-paragraph-wrap","dist-tags":{"latest":"0.1.0"},"versions":{"0.0.1":{"name":"@ngrok/remark-mdx-no-paragraph-wrap","version":"0.0.1","keywords":["mdast","mdx","paragraph","preserve","remark","remark-plugin","unified","unwrap"],"author":{"name":"ngrok"},"license":"MIT","_id":"@ngrok/remark-mdx-no-paragraph-wrap@0.0.1","maintainers":[{"name":"inconshreveable","email":"alan@ngrok.com"},{"name":"cody.js","email":"cody@ngrok.com"},{"name":"eng-npm-bot","email":"eng-npm-bot@ngrok.com"},{"name":"pshafton","email":"peter@ngrok.com"},{"name":"bmpngrok","email":"b.pollack@ngrok.com"}],"homepage":"https://github.com/ngrok-oss/mantle/tree/main/packages/remark-mdx-no-paragraph-wrap","bugs":{"url":"https://github.com/ngrok-oss/mantle/issues"},"dist":{"shasum":"6da6dd60e3b0cbebbe93924a0b0296e298aaf540","tarball":"https://registry.npmjs.org/@ngrok/remark-mdx-no-paragraph-wrap/-/remark-mdx-no-paragraph-wrap-0.0.1.tgz","fileCount":6,"integrity":"sha512-zu0y1x8GFmVuXb+Ozr17uIwNdgreGFfEe2naYCZqgeldfvaGu6biNmFH9+CccE7OcDDEK1MnvwO6UeqKGxAI6g==","signatures":[{"sig":"MEUCIQCGS3S7nWgjEVG49DMRHT+89qAnYeZJTWZQP9OE9yuJ3AIgXkL5EY+hIfMPVLwfysQx2fxbx36eTAy2lt5OZEi82n0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":10941},"type":"module","_from":"file:ngrok-remark-mdx-no-paragraph-wrap-0.0.1.tgz","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./package.json":"./package.json"},"scripts":{"test":"TZ=UTC vitest run","build":"tsup","clean":"rm -rf dist","prebuild":"pnpm run clean","typecheck":"tsc --noEmit"},"_npmUser":{"name":"cody.js","email":"cody@ngrok.com"},"_resolved":"/private/var/folders/8w/dcktjb653pz4cnwgtw23jtbr0000gn/T/03969ca3815f62c26ed199e636e82602/ngrok-remark-mdx-no-paragraph-wrap-0.0.1.tgz","_integrity":"sha512-zu0y1x8GFmVuXb+Ozr17uIwNdgreGFfEe2naYCZqgeldfvaGu6biNmFH9+CccE7OcDDEK1MnvwO6UeqKGxAI6g==","repository":{"url":"git+https://github.com/ngrok-oss/mantle.git","type":"git","directory":"packages/remark-mdx-no-paragraph-wrap"},"_npmVersion":"11.10.0","description":"Remark plugin that prevents MDX from wrapping JSX component children in <p> tags.","directories":{},"_nodeVersion":"24.13.1","dependencies":{"@types/mdast":"4.0.4","unist-util-visit":"5.1.0"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"8.5.1","typescript":"5.9.3","@mdx-js/mdx":"3.1.1","@cfg/tsconfig":"1.0.0","mdast-util-mdx-jsx":"3.2.0"},"peerDependencies":{"@mdx-js/mdx":">=3.0.0 || >=4.0.0","@mdx-js/rollup":">=3.0.0 || >=4.0.0"},"peerDependenciesMeta":{"@mdx-js/mdx":{"optional":true},"@mdx-js/rollup":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/remark-mdx-no-paragraph-wrap_0.0.1_1771007763757_0.10545543365165355","host":"s3://npm-registry-packages-npm-production"}},"0.1.0":{"name":"@ngrok/remark-mdx-no-paragraph-wrap","version":"0.1.0","description":"Remark plugin that prevents MDX from wrapping JSX component children in <p> tags.","keywords":["mdast","mdx","paragraph","preserve","remark","remark-plugin","unified","unwrap"],"url":"https://github.com/ngrok-oss/remark-mdx-no-paragraph-wrap","license":"MIT","author":{"name":"ngrok"},"repository":{"type":"git","url":"git+https://github.com/ngrok-oss/remark-mdx-no-paragraph-wrap.git"},"type":"module","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./package.json":"./package.json"},"dependencies":{"@types/mdast":"4.0.4","unist-util-visit":"5.1.0"},"devDependencies":{"@changesets/changelog-github":"0.5.2","@changesets/cli":"2.29.8","@mdx-js/mdx":"3.1.1","@total-typescript/ts-reset":"0.6.1","@types/node":"24.10.12","mdast-util-mdx-jsx":"3.2.0","oxfmt":"0.28.0","oxlint":"1.43.0","tsx":"4.21.0","typescript":"5.9.3","vitest":"4.0.18"},"peerDependencies":{"@mdx-js/mdx":">=3.0.0 || >=4.0.0","@mdx-js/rollup":">=3.0.0 || >=4.0.0"},"peerDependenciesMeta":{"@mdx-js/mdx":{"optional":true},"@mdx-js/rollup":{"optional":true}},"scripts":{"build":"pnpm run compile","changeset":"changeset","compile":"tsc --project tsconfig.compile.json","fmt:check":"oxfmt --check .","fmt":"oxfmt --write .","lint:fix":"oxlint --fix .","lint":"oxlint .","precompile":"rm -rf dist tsconfig.compile.tsbuildinfo","test":"vitest","typecheck":"tsc --noEmit"},"_id":"@ngrok/remark-mdx-no-paragraph-wrap@0.1.0","bugs":{"url":"https://github.com/ngrok-oss/remark-mdx-no-paragraph-wrap/issues"},"homepage":"https://github.com/ngrok-oss/remark-mdx-no-paragraph-wrap#readme","_integrity":"sha512-BQjOZB9J+9xbAQlPkQf9WmqRsnEo8NLToYNhX0CV0KWJAwpq3XhU3Ucj1wbg8nu8KGCak2CUoYJ5ohi/3orP6w==","_resolved":"/tmp/84ff14889dfae4801d8c6bee28df824e/ngrok-remark-mdx-no-paragraph-wrap-0.1.0.tgz","_from":"file:ngrok-remark-mdx-no-paragraph-wrap-0.1.0.tgz","_nodeVersion":"24.13.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-BQjOZB9J+9xbAQlPkQf9WmqRsnEo8NLToYNhX0CV0KWJAwpq3XhU3Ucj1wbg8nu8KGCak2CUoYJ5ohi/3orP6w==","shasum":"8187a32f0462d07fb1a2ec8829298c8d51593f6a","tarball":"https://registry.npmjs.org/@ngrok/remark-mdx-no-paragraph-wrap/-/remark-mdx-no-paragraph-wrap-0.1.0.tgz","fileCount":6,"unpackedSize":10593,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@ngrok%2fremark-mdx-no-paragraph-wrap@0.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIET1TG9ytGZsRl3Tbn6pgcsAJy6bICDnzO552F0AvHA8AiAupaBhP+KKINUW+xnJe3kGNZzuNP567K3oiaRYC43WfQ=="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:315aed75-5c65-4252-89b0-d0eb02212f99"}},"directories":{},"maintainers":[{"name":"inconshreveable","email":"alan@ngrok.com"},{"name":"cody.js","email":"cody@ngrok.com"},{"name":"eng-npm-bot","email":"eng-npm-bot@ngrok.com"},{"name":"pshafton","email":"peter@ngrok.com"},{"name":"bmpngrok","email":"b.pollack@ngrok.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/remark-mdx-no-paragraph-wrap_0.1.0_1771101690155_0.5464561095784546"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-13T18:36:03.637Z","modified":"2026-02-14T20:41:30.700Z","0.0.1":"2026-02-13T18:36:03.982Z","0.1.0":"2026-02-14T20:41:30.300Z"},"bugs":{"url":"https://github.com/ngrok-oss/remark-mdx-no-paragraph-wrap/issues"},"author":{"name":"ngrok"},"license":"MIT","homepage":"https://github.com/ngrok-oss/remark-mdx-no-paragraph-wrap#readme","keywords":["mdast","mdx","paragraph","preserve","remark","remark-plugin","unified","unwrap"],"repository":{"type":"git","url":"git+https://github.com/ngrok-oss/remark-mdx-no-paragraph-wrap.git"},"description":"Remark plugin that prevents MDX from wrapping JSX component children in <p> tags.","maintainers":[{"name":"inconshreveable","email":"alan@ngrok.com"},{"name":"cody.js","email":"cody@ngrok.com"},{"name":"eng-npm-bot","email":"eng-npm-bot@ngrok.com"},{"name":"pshafton","email":"peter@ngrok.com"},{"name":"bmpngrok","email":"b.pollack@ngrok.com"}],"readme":"# @ngrok/remark-mdx-no-paragraph-wrap\n\nRemark plugin that prevents MDX from wrapping JSX component children in `<p>` tags.\n\n## Why\n\nMDX automatically wraps multiline content inside JSX components in `<p>` tags. For prose content this is great, but it causes **invalid or unexpected nesting** when using custom components like headers, cards, or layout wrappers:\n\n```jsx\nconst PageHeader = ({ children, id }) => <h1 id={id}>{children}</h1>;\n```\n\n```mdx\n<PageHeader id=\"philosophy\">Philosophy</PageHeader>\n```\n\nMDX compiles this into:\n\n```html\n<h1 id=\"philosophy\">\n\t<p>Philosophy</p>\n</h1>\n```\n\nThat `<p>` inside `<h1>` is invalid HTML — it breaks styling, violates nesting rules, and causes hydration mismatches.\n\n## What\n\nThis remark plugin **automatically** strips paragraph nodes from inside **all** MDX JSX elements at the mdast (Markdown AST) level — before they are ever converted to HTML. No sentinel attribute or manual annotation is needed.\n\n```mdx\n<PageHeader id=\"philosophy\">Philosophy</PageHeader>\n```\n\nCompiles to:\n\n```html\n<h1 id=\"philosophy\">Philosophy</h1>\n```\n\nNo `<p>` wrapper. All JSX elements are handled automatically.\n\n## Installation\n\n| package manager | command                                             |\n| --------------- | --------------------------------------------------- |\n| npm             | npm install -DE @ngrok/remark-mdx-no-paragraph-wrap |\n| pnpm            | pnpm add -DE @ngrok/remark-mdx-no-paragraph-wrap    |\n| bun             | bun add -DE @ngrok/remark-mdx-no-paragraph-wrap     |\n| yarn            | yarn add -DE @ngrok/remark-mdx-no-paragraph-wrap    |\n\n## Configuration\n\n### With `@mdx-js/rollup` (Vite, Rollup)\n\n```ts\nimport mdx from \"@mdx-js/rollup\";\nimport { remarkMdxNoParagraphWrap } from \"@ngrok/remark-mdx-no-paragraph-wrap\";\n\nexport default {\n\tplugins: [\n\t\tmdx({\n\t\t\tremarkPlugins: [remarkMdxNoParagraphWrap],\n\t\t}),\n\t],\n};\n```\n\n### With `@mdx-js/mdx` (compile API)\n\n```ts\nimport { compile } from \"@mdx-js/mdx\";\nimport { remarkMdxNoParagraphWrap } from \"@ngrok/remark-mdx-no-paragraph-wrap\";\n\nconst result = await compile(mdxSource, {\n\tremarkPlugins: [remarkMdxNoParagraphWrap],\n});\n```\n\n## How it works\n\nThe plugin operates at the **mdast (Markdown AST)** level, running as a remark transform before MDX converts to HTML (hast).\n\n1. **Walk the tree** — uses `unist-util-visit` to traverse all nodes.\n2. **Find JSX elements** — looks for `mdxJsxFlowElement` and `mdxJsxTextElement` nodes.\n3. **Unwrap paragraphs** — recursively walks each JSX element's children, replacing any `paragraph` nodes with their own children (flattening them).\n\nThe unwrapping is recursive, so it handles nested structures correctly — paragraph nodes at any depth within JSX components are removed. Normal markdown prose outside JSX elements is unaffected.\n\nExplicit `<p>` tags written in JSX (e.g., `<p className=\"custom\">text</p>`) are **not** affected — MDX parses them as JSX element nodes, not mdast `paragraph` nodes, so they pass through untouched.\n\n## API\n\n### `remarkMdxNoParagraphWrap()`\n\nReturns a remark transformer function. No options are needed — all MDX JSX elements are processed automatically.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}