diff --git a/.gitignore b/.gitignore
index aa03fe825..4b6ddf80c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -26,3 +26,4 @@ lib/
.vercel
src/**/*.mjs
+scripts/**/*.mjs
diff --git a/next.config.mjs b/next.config.mjs
index fc4cee98b..13b1735c7 100644
--- a/next.config.mjs
+++ b/next.config.mjs
@@ -7,7 +7,7 @@ import remarkFrontmatter from 'remark-frontmatter'
import remarkMdxFrontmatter from "remark-mdx-frontmatter";
import { createLoader } from 'simple-functional-loader'
-const bsconfig = JSON.parse(fs.readFileSync("./bsconfig.json"))
+const bsconfig = JSON.parse(fs.readFileSync("./rescript.json"))
const { ProvidePlugin } = webpack;
diff --git a/package-lock.json b/package-lock.json
index 60ae963dc..efa793c63 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,8 +11,7 @@
"dependencies": {
"@headlessui/react": "^1.2.0",
"@mdx-js/loader": "^2.3.0",
- "@rescript/react": "^0.10.3",
- "@ryyppy/rescript-promise": "2.1.0",
+ "@rescript/react": "^0.12.0-alpha.3",
"codemirror": "^5.54.0",
"docson": "^2.1.0",
"eslint-config-next": "^13.1.1",
@@ -47,7 +46,7 @@
"postcss": "^8.4.27",
"postcss-cli": "^8.3.0",
"reanalyze": "^2.16.0",
- "rescript": "^10.1.4",
+ "rescript": "^11.0.0-rc.6",
"simple-functional-loader": "^1.2.1",
"tailwindcss": "^3.3.3"
},
@@ -973,12 +972,12 @@
}
},
"node_modules/@rescript/react": {
- "version": "0.10.3",
- "resolved": "https://registry.npmjs.org/@rescript/react/-/react-0.10.3.tgz",
- "integrity": "sha512-Lf9rzrR3bQPKJjOK3PBRa/B3xrJ7CqQ1HYr9VHPVxJidarIJJFZBhj0Dg1uZURX+Wg/xiP0PHFxXmdj2bK8Vxw==",
+ "version": "0.12.0-alpha.3",
+ "resolved": "https://registry.npmjs.org/@rescript/react/-/react-0.12.0-alpha.3.tgz",
+ "integrity": "sha512-/S1uj77RPDzuLg3Ofb8KKU3Vppqy97/vF6bBdBZ+saIO9bpHVlsmmJyJG8QXjGZKE+aMynrrR3Tj4+9+5OzLdw==",
"peerDependencies": {
- "react": ">=16.8.1",
- "react-dom": ">=16.8.1"
+ "react": ">=18.0.0",
+ "react-dom": ">=18.0.0"
}
},
"node_modules/@rushstack/eslint-patch": {
@@ -986,11 +985,6 @@
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.3.2.tgz",
"integrity": "sha512-V+MvGwaHH03hYhY+k6Ef/xKd6RYlc4q8WBx+2ANmipHJcKuktNcI/NgEsJgdSUF6Lw32njT6OnrRsKYCdgHjYw=="
},
- "node_modules/@ryyppy/rescript-promise": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/@ryyppy/rescript-promise/-/rescript-promise-2.1.0.tgz",
- "integrity": "sha512-+dW6msBrj2Lr2hbEMX+HoWCvN89qVjl94RwbYWJgHQuj8jm/izdPC0YzxgpGoEFdeAEW2sOozoLcYHxT6o5WXQ=="
- },
"node_modules/@swc/helpers": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.1.tgz",
@@ -8495,16 +8489,18 @@
}
},
"node_modules/rescript": {
- "version": "10.1.4",
- "resolved": "https://registry.npmjs.org/rescript/-/rescript-10.1.4.tgz",
- "integrity": "sha512-FFKlS9AG/XrLepWsyw7B+A9DtQBPWEPDPDKghV831Y2KGbie+eeFBOS0xtRHp0xbt7S0N2Dm6hhX+kTZQ/3Ybg==",
+ "version": "11.0.0-rc.6",
+ "resolved": "https://registry.npmjs.org/rescript/-/rescript-11.0.0-rc.6.tgz",
+ "integrity": "sha512-2nqdpQxLgQGNp0Rb8AFn5cM3kwRTd54zLvchqCsK3iLOe1CJwdVW5nEF7lsJbFTqihl8W6Va1y7SbFxY3FNxOQ==",
"dev": true,
"hasInstallScript": true,
"bin": {
"bsc": "bsc",
- "bsrefmt": "bsrefmt",
"bstracing": "lib/bstracing",
"rescript": "rescript"
+ },
+ "engines": {
+ "node": ">=10"
}
},
"node_modules/resolve": {
@@ -10987,9 +10983,9 @@
}
},
"@rescript/react": {
- "version": "0.10.3",
- "resolved": "https://registry.npmjs.org/@rescript/react/-/react-0.10.3.tgz",
- "integrity": "sha512-Lf9rzrR3bQPKJjOK3PBRa/B3xrJ7CqQ1HYr9VHPVxJidarIJJFZBhj0Dg1uZURX+Wg/xiP0PHFxXmdj2bK8Vxw==",
+ "version": "0.12.0-alpha.3",
+ "resolved": "https://registry.npmjs.org/@rescript/react/-/react-0.12.0-alpha.3.tgz",
+ "integrity": "sha512-/S1uj77RPDzuLg3Ofb8KKU3Vppqy97/vF6bBdBZ+saIO9bpHVlsmmJyJG8QXjGZKE+aMynrrR3Tj4+9+5OzLdw==",
"requires": {}
},
"@rushstack/eslint-patch": {
@@ -10997,11 +10993,6 @@
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.3.2.tgz",
"integrity": "sha512-V+MvGwaHH03hYhY+k6Ef/xKd6RYlc4q8WBx+2ANmipHJcKuktNcI/NgEsJgdSUF6Lw32njT6OnrRsKYCdgHjYw=="
},
- "@ryyppy/rescript-promise": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/@ryyppy/rescript-promise/-/rescript-promise-2.1.0.tgz",
- "integrity": "sha512-+dW6msBrj2Lr2hbEMX+HoWCvN89qVjl94RwbYWJgHQuj8jm/izdPC0YzxgpGoEFdeAEW2sOozoLcYHxT6o5WXQ=="
- },
"@swc/helpers": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.1.tgz",
@@ -16250,9 +16241,9 @@
"dev": true
},
"rescript": {
- "version": "10.1.4",
- "resolved": "https://registry.npmjs.org/rescript/-/rescript-10.1.4.tgz",
- "integrity": "sha512-FFKlS9AG/XrLepWsyw7B+A9DtQBPWEPDPDKghV831Y2KGbie+eeFBOS0xtRHp0xbt7S0N2Dm6hhX+kTZQ/3Ybg==",
+ "version": "11.0.0-rc.6",
+ "resolved": "https://registry.npmjs.org/rescript/-/rescript-11.0.0-rc.6.tgz",
+ "integrity": "sha512-2nqdpQxLgQGNp0Rb8AFn5cM3kwRTd54zLvchqCsK3iLOe1CJwdVW5nEF7lsJbFTqihl8W6Va1y7SbFxY3FNxOQ==",
"dev": true
},
"resolve": {
diff --git a/package.json b/package.json
index 4a279938e..2ee5bb1f4 100644
--- a/package.json
+++ b/package.json
@@ -17,8 +17,7 @@
"dependencies": {
"@headlessui/react": "^1.2.0",
"@mdx-js/loader": "^2.3.0",
- "@rescript/react": "^0.10.3",
- "@ryyppy/rescript-promise": "2.1.0",
+ "@rescript/react": "^0.12.0-alpha.3",
"codemirror": "^5.54.0",
"docson": "^2.1.0",
"eslint-config-next": "^13.1.1",
@@ -60,7 +59,7 @@
"postcss": "^8.4.27",
"postcss-cli": "^8.3.0",
"reanalyze": "^2.16.0",
- "rescript": "^10.1.4",
+ "rescript": "^11.0.0-rc.6",
"simple-functional-loader": "^1.2.1",
"tailwindcss": "^3.3.3"
}
diff --git a/pages/try.js b/pages/try.js
index fe297fd6c..f9bbdf9fc 100644
--- a/pages/try.js
+++ b/pages/try.js
@@ -1,19 +1 @@
-import dynamic from "next/dynamic";
-
-export { getStaticProps } from "src/Try.mjs";
-import Try from "src/Try.mjs";
-
-const Playground = dynamic(() => import("src/Playground.mjs"), {
- ssr: false,
- loading: () => Loading...
-});
-
-function Comp(props) {
- return (
-
-
-
- );
-}
-
-export default Comp;
+export { getStaticProps, default } from "src/Try.mjs";
diff --git a/bsconfig.json b/rescript.json
similarity index 85%
rename from bsconfig.json
rename to rescript.json
index f0243a6d6..a6495f63e 100644
--- a/bsconfig.json
+++ b/rescript.json
@@ -1,13 +1,13 @@
{
"name": "rescript-lang.org",
"namespace": false,
- "reason": {
- "react-jsx": 3
+ "jsx": {
+ "version": 4
},
"bs-dependencies": [
- "@rescript/react",
- "@ryyppy/rescript-promise"
+ "@rescript/react"
],
+ "uncurried": true,
"ppx-flags": [],
"sources": [
{
diff --git a/scripts/generate_feed.mjs b/scripts/generate_feed.mjs
deleted file mode 100644
index dd4845a93..000000000
--- a/scripts/generate_feed.mjs
+++ /dev/null
@@ -1,12 +0,0 @@
-// Generated by ReScript, PLEASE EDIT WITH CARE
-
-import * as BlogApi from "../src/common/BlogApi.mjs";
-
-var content = BlogApi.RssFeed.toXmlString(undefined, undefined, BlogApi.RssFeed.getLatest(undefined, undefined, undefined));
-
-console.log(content);
-
-export {
- content ,
-}
-/* content Not a pure module */
diff --git a/src/Blog.res b/src/Blog.res
index 63c66cc0b..f2c0c57d2 100644
--- a/src/Blog.res
+++ b/src/Blog.res
@@ -101,10 +101,7 @@ module BlogCard = {
}}
-
+
{
let className = "absolute top-0 h-full w-full object-cover"
switch previewImg {
@@ -115,7 +112,7 @@ module BlogCard = {
-
+
{React.string(title)}
@@ -156,7 +153,7 @@ module FeatureCard = {
~maxHeight="25.4375rem",
(),
)}>
-
+
{switch badge {
| Some(badge) =>
@@ -202,7 +199,7 @@ module FeatureCard = {
{React.string(firstParagraph)}
-
+
@@ -304,13 +301,13 @@ let default = (props: props): React.element => {
diff --git a/src/BlogArticle.res b/src/BlogArticle.res
index 4f119899f..5ce179f44 100644
--- a/src/BlogArticle.res
+++ b/src/BlogArticle.res
@@ -22,7 +22,7 @@ module Params = {
type t = {slug: string}
}
-type props = {mdxSource: Mdx.Remote.output, isArchived: bool, path: string}
+type props = {mdxSource: MdxRemote.output, isArchived: bool, path: string}
module Line = {
@react.component
@@ -116,29 +116,16 @@ module BlogHeader = {
}
}
-type remarkPlugin
-@module("remark-comment") external remarkComment: remarkPlugin = "default"
-@module("remark-gfm") external remarkGfm: remarkPlugin = "default"
-@module("remark-frontmatter") external remarkFrontmatter: remarkPlugin = "default"
-
-let mdxOptions = {"remarkPlugins": [remarkComment, remarkGfm, remarkFrontmatter]}
-
-external asProps: {..} => {"props": Mdx.Remote.output} = "%identity"
-
let default = (props: props) => {
let {mdxSource, isArchived, path} = props
- let mdxProps = {
- "frontmatter": mdxSource.frontmatter,
- "scope": mdxSource.scope,
- "compiledSource": mdxSource.compiledSource,
- "components": Markdown.default,
- "options": {
- "mdxOptions": mdxOptions,
- },
- }
-
- let children = React.createElement(Mdx.MDXRemote.make, asProps(mdxProps))
+ let children =
+
let fm = mdxSource.frontmatter->BlogFrontmatter.decode
@@ -230,11 +217,11 @@ let getStaticProps: Next.GetStaticProps.t = async ctx => {
let isArchived = Js.String2.startsWith(path, "archive/")
- let source = filePath->Node.Fs.readFileSync(#utf8)
+ let source = filePath->Node.Fs.readFileSync
- let mdxSource = await Mdx.Remote.serialize(
+ let mdxSource = await MdxRemote.serialize(
source,
- {"parseFrontmatter": true, "mdxOptions": mdxOptions},
+ {parseFrontmatter: true, mdxOptions: MdxRemote.defaultMdxOptions},
)
let props = {mdxSource, isArchived, path}
diff --git a/src/BlogArticle.resi b/src/BlogArticle.resi
index 55c97b853..0f1ab1e16 100644
--- a/src/BlogArticle.resi
+++ b/src/BlogArticle.resi
@@ -2,7 +2,7 @@ module Params: {
type t = {slug: string}
}
-type props = {mdxSource: Mdx.Remote.output, isArchived: bool, path: string}
+type props = {mdxSource: MdxRemote.output, isArchived: bool, path: string}
let default: props => React.element
diff --git a/src/Packages.res b/src/Packages.res
index a321824cf..3b2aa851c 100644
--- a/src/Packages.res
+++ b/src/Packages.res
@@ -433,14 +433,14 @@ let default = (props: props) => {
// On first render, the router query is undefined so we set a flag.
let firstRenderDone = React.useRef(false)
- React.useEffect0(() => {
+ React.useEffect(() => {
firstRenderDone.current = true
None
- })
+ }, [])
// On second render, this hook runs one more time to actually trigger the search.
- React.useEffect1(() => {
+ React.useEffect(() => {
router.query->Js.Dict.get("search")->Belt.Option.forEach(onValueChange)
None
@@ -453,7 +453,7 @@ let default = (props: props) => {
})
// When the search term changes, update the router query accordingly.
- React.useEffect1(() => {
+ React.useEffect(() => {
switch state {
| All => updateQuery("")
| Filtered(value) => updateQuery(value)
@@ -475,7 +475,7 @@ let default = (props: props) => {
-
+
{React.string("Libraries & Bindings")}
@@ -494,7 +494,7 @@ let default = (props: props) => {
-
+
@@ -517,10 +517,10 @@ type npmData = {
module Response = {
type t
- @send external json: t => Js.Promise.t
= "json"
+ @send external json: t => promise = "json"
}
-@val external fetchNpmPackages: string => Js.Promise.t = "fetch"
+@val external fetchNpmPackages: string => promise = "fetch"
let getStaticProps: Next.GetStaticProps.revalidate = async _ctx => {
let response = await fetchNpmPackages(
@@ -544,7 +544,7 @@ let getStaticProps: Next.GetStaticProps.revalidate = async _ctx =>
let index_data_dir = Node.Path.join2(Node.Process.cwd(), "./data")
let urlResources =
Node.Path.join2(index_data_dir, "packages_url_resources.json")
- ->Node.Fs.readFileSync(#utf8)
+ ->Node.Fs.readFileSync
->Js.Json.parseExn
->unsafeToUrlResource
let props: props = {
diff --git a/src/Playground.res b/src/Playground.res
index 4ae260543..04fbde4dc 100644
--- a/src/Playground.res
+++ b/src/Playground.res
@@ -1098,7 +1098,7 @@ module ControlPanel = {
let make = (~createShareLink: unit => string, ~actionIndicatorKey: string) => {
let (state, setState) = React.useState(() => Init)
- React.useEffect1(() => {
+ React.useEffect(() => {
setState(_ => Init)
None
}, [actionIndicatorKey])
@@ -1420,11 +1420,12 @@ module App = {
let initialReContent = `Js.log("Hello Reason 3.6!");`
-let default = (~props: Try.props) => {
+@react.component
+let make = (~versions: array) => {
let router = Next.Router.useRouter()
let versions =
- props.versions
+ versions
->Belt.Array.keepMap(v => v->CompilerManagerHook.Semver.parse)
->Js.Array2.sortInPlaceWith((a, b) => {
let cmp = ({CompilerManagerHook.Semver.major: major, minor, patch, _}) => {
@@ -1506,7 +1507,7 @@ let default = (~props: Try.props) => {
let typingTimer = React.useRef(None)
let timeoutCompile = React.useRef(() => ())
- React.useEffect1(() => {
+ React.useEffect(() => {
timeoutCompile.current = () =>
switch compilerState {
| Ready(ready) => compilerDispatch(CompileCode(ready.targetLang, editorCode.current))
@@ -1547,16 +1548,16 @@ let default = (~props: Try.props) => {
}
}
- React.useEffect0(() => {
+ React.useEffect(() => {
Webapi.Window.addEventListener("resize", onResize)
Some(() => Webapi.Window.removeEventListener("resize", onResize))
- })
+ }, [])
// To force CodeMirror render scrollbar on first render
React.useLayoutEffect(() => {
onResize()
None
- })
+ }, [])
let onMouseDown = _ => isDragging.current = true
@@ -1628,7 +1629,7 @@ let default = (~props: Try.props) => {
Webapi.Window.removeEventListener("mouseup", onMouseUp)
},
)
- })
+ }, [])
let cmErrors = switch compilerState {
| Ready({result}) =>
@@ -1638,7 +1639,7 @@ let default = (~props: Try.props) => {
| SyntaxErr(locMsgs)
| TypecheckErr(locMsgs)
| OtherErr(locMsgs) =>
- Js.Array2.map(locMsgs, locMsgToCmError(~kind=#Error))
+ Js.Array2.map(locMsgs, locMsgToCmError(~kind=#Error, ...))
| WarningErr(warnings) =>
Js.Array2.map(warnings, warning => {
switch warning {
@@ -1657,7 +1658,7 @@ let default = (~props: Try.props) => {
locMsgToCmError(~kind=#Warning, details)
}
})
- | Conv(Fail({details})) => Js.Array2.map(details, locMsgToCmError(~kind=#Error))
+ | Conv(Fail({details})) => Js.Array2.map(details, locMsgToCmError(~kind=#Error, ...))
| Comp(_)
| Conv(_)
| Nothing => []
diff --git a/src/Playground.resi b/src/Playground.resi
index 72031edb8..33288c00c 100644
--- a/src/Playground.resi
+++ b/src/Playground.resi
@@ -1 +1,2 @@
-let default: (~props: Try.props) => React.element
+@react.component
+let make: (~versions: array) => React.element
diff --git a/src/SyntaxLookup.res b/src/SyntaxLookup.res
index f8623893d..811140cf6 100644
--- a/src/SyntaxLookup.res
+++ b/src/SyntaxLookup.res
@@ -112,15 +112,15 @@ external scrollTo: (int, int) => unit = "scrollTo"
let scrollToTop = () => scrollTo(0, 0)
-type props = {mdxSources: array}
+type props = {mdxSources: array}
type params = {slug: string}
let decode = (json: Js.Json.t) => {
open Json.Decode
- let id = json->field("id", string, _)
- let keywords = json->field("keywords", array(string), _)
- let name = json->field("name", string, _)
- let summary = json->field("summary", string, _)
+ let id = json->(field("id", string, _))
+ let keywords = json->(field("keywords", array(string, ...), _))
+ let name = json->(field("name", string, _))
+ let summary = json->(field("summary", string, _))
let category = json->field("category", string, _)->Category.fromString
{
@@ -132,34 +132,19 @@ let decode = (json: Js.Json.t) => {
}
}
-type remarkPlugin
-@module("remark-comment") external remarkComment: remarkPlugin = "default"
-@module("remark-gfm") external remarkGfm: remarkPlugin = "default"
-@module("remark-frontmatter") external remarkFrontmatter: remarkPlugin = "default"
-
-let mdxOptions = {"remarkPlugins": [remarkComment, remarkGfm, remarkFrontmatter]}
-
-external asProps: {..} => {"props": Mdx.Remote.output} = "%identity"
-
let default = (props: props) => {
let {mdxSources} = props
let allItems = mdxSources->Js.Array2.map(mdxSource => {
let {id, keywords, category, summary, name} = decode(mdxSource.frontmatter)
- let mdxProps = {
- "frontmatter": mdxSource.frontmatter,
- "scope": mdxSource.scope,
- "compiledSource": mdxSource.compiledSource,
- "components": Markdown.default,
- "options": {
- "mdxOptions": mdxOptions,
- },
- }
-
- let children = React.createElement(Mdx.MDXRemote.make, asProps(mdxProps))
-
- // let children = MdxUtils.createElement(mdxSource)
+ let children =
+
{id, keywords, category, summary, name, children}
})
@@ -196,7 +181,7 @@ let default = (props: props) => {
// [A] The page first loads.
// [B] The search box is cleared.
// [C] The search box value exactly matches an item name.
- React.useEffect1(() => {
+ React.useEffect(() => {
switch getAnchor(router.asPath) {
| None => setState(_ => ShowAll)
| Some(anchor) =>
@@ -248,9 +233,8 @@ let default = (props: props) => {
Order all items in tag groups
*/
let categories = {
- open Category
let initial = [
- Decorators,
+ Category.Decorators,
Operators,
LanguageConstructs,
BuiltInFunctions,
@@ -258,7 +242,7 @@ let default = (props: props) => {
SpecialValues,
Other,
]->Belt.Array.map(cat => {
- (cat->toString, [])
+ (cat->Category.toString, [])
})
let items = switch state {
@@ -268,7 +252,7 @@ let default = (props: props) => {
}
Belt.Array.reduce(items, Js.Dict.fromArray(initial), (acc, item) => {
- let key = item.category->toString
+ let key = item.category->Category.toString
Js.Dict.get(acc, key)->Belt.Option.mapWithDefault(acc, items => {
Js.Array2.push(items, item)->ignore
Js.Dict.set(acc, key, items)
@@ -349,11 +333,11 @@ let default = (props: props) => {
@@ -367,8 +351,11 @@ let getStaticProps: Next.GetStaticProps.t = async _ctx => {
let allFiles = Node.Fs.readdirSync(dir)->Js.Array2.map(async file => {
let fullPath = Node.Path.join2(dir, file)
- let source = fullPath->Node.Fs.readFileSync(#utf8)
- await Mdx.Remote.serialize(source, {"parseFrontmatter": true, "mdxOptions": mdxOptions})
+ let source = fullPath->Node.Fs.readFileSync
+ await MdxRemote.serialize(
+ source,
+ {parseFrontmatter: true, mdxOptions: MdxRemote.defaultMdxOptions},
+ )
})
let mdxSources = await Js.Promise2.all(allFiles)
diff --git a/src/Try.res b/src/Try.res
index e22200db3..2562b92ac 100644
--- a/src/Try.res
+++ b/src/Try.res
@@ -1,7 +1,17 @@
-let default = (props: {"children": React.element}) => {
+type props = {versions: array}
+
+let default = props => {
let overlayState = React.useState(() => false)
- let playground = props["children"]
+ let lazyPlayground = Next.Dynamic.dynamic(
+ async () => await Js.import(Playground.make),
+ {
+ ssr: false,
+ loading: () => {React.string("Loading...")} ,
+ },
+ )
+
+ let playground = React.createElement(lazyPlayground, {versions: props.versions})
<>
@@ -17,8 +27,6 @@ let default = (props: {"children": React.element}) => {
>
}
-type props = {versions: array}
-
let getStaticProps: Next.GetStaticProps.t = async _ => {
let versions = {
let response = await Webapi.Fetch.fetch("https://cdn.rescript-lang.org/")
diff --git a/src/Try.resi b/src/Try.resi
index 2611af9cf..5fec66502 100644
--- a/src/Try.resi
+++ b/src/Try.resi
@@ -1,3 +1,3 @@
-let default: {"children": React.element} => React.element
type props = {versions: array}
+let default: props => React.element
let getStaticProps: Next.GetStaticProps.t
diff --git a/src/bindings/MdxProvider.res b/src/bindings/MdxProvider.res
new file mode 100644
index 000000000..fa1e7e9c9
--- /dev/null
+++ b/src/bindings/MdxProvider.res
@@ -0,0 +1,3 @@
+@module("@mdx-js/react") @react.component
+external make: (~components: MarkdownComponents.t, ~children: React.element=?) => React.element =
+ "MDXProvider"
diff --git a/src/bindings/MdxRemote.res b/src/bindings/MdxRemote.res
new file mode 100644
index 000000000..fd8be636d
--- /dev/null
+++ b/src/bindings/MdxRemote.res
@@ -0,0 +1,34 @@
+type output = {frontmatter: Js.Json.t, compiledSource: string, scope: Js.Json.t}
+
+type mdxPlugin
+
+type mdxOptions = {
+ remarkPlugins?: array,
+ rehypePlugins?: array,
+}
+
+type serializeOptions = {
+ parseFrontmatter: bool,
+ mdxOptions: mdxOptions,
+}
+
+@module("next-mdx-remote/serialize")
+external serialize: (string, serializeOptions) => promise