diff --git a/_blogposts/archive/bucklescript-release-3-0-0.mdx b/_blogposts/archive/bucklescript-release-3-0-0.mdx
index bfd464930..335a0797f 100644
--- a/_blogposts/archive/bucklescript-release-3-0-0.mdx
+++ b/_blogposts/archive/bucklescript-release-3-0-0.mdx
@@ -1,10 +1,10 @@
---
author: hongbo
-date: "2018-04-16"
+date: "2018-04-16"
previewImg:
category: compiler
badge: release
-title: Announcing BuckleScript 3.0
+title: Announcing BuckleScript 3.0
description: |
---
@@ -19,8 +19,7 @@ description: |
This caused quite a bit of confusion for newcomers. It now compiles to JS
`true`/`false`. Special thanks to [Cristiano](https://twitter.com/ccrisccris)
for all the hard work.
-- New [object type
- feature](/docs/reason-compiler/latest/object#abstract-record-mode). This is
+- New `[bs.deriving abstract`] feature. This is
an experimental and potentially much better way to bind to JS objects that
potentially obsoletes the need for a few other APIs. Please see the linked
docs and help us test it!
diff --git a/_blogposts/archive/state-of-reasonml-org-2020-q2-pt1.mdx b/_blogposts/archive/state-of-reasonml-org-2020-q2-pt1.mdx
index f02a3d069..f78193850 100644
--- a/_blogposts/archive/state-of-reasonml-org-2020-q2-pt1.mdx
+++ b/_blogposts/archive/state-of-reasonml-org-2020-q2-pt1.mdx
@@ -73,7 +73,7 @@ Our goal is to have a properly curated, well structured and streamlined overview
-It didn't take long until we realized that we can't just keep the upstream version in its original form, so we started to make adaptations where it made sense. We also accepted new additions from the community, such as explanations about [function signatures on optional arguments](/docs/manual/latest/function#signatures-and-type-annotations) in the Reason manual, or a new [decorator overview](/docs/reason-compiler/latest/decorators) in the BuckleScript section.
+It didn't take long until we realized that we can't just keep the upstream version in its original form, so we started to make adaptations where it made sense. We also accepted new additions from the community, such as explanations about [function signatures on optional arguments](/docs/manual/latest/function#signatures-and-type-annotations) in the Reason manual, or a new decorator overview in the BuckleScript section.
That said, we do keep track of new changes on the upstream sources and cherry-pick changes if necessary. To make this process more transparent, we introduced a version table on our [startpage](/) to make it easier to see the latest cherry-pick commit for each resource (ReasonML, BuckleScript, etc.).
diff --git a/pages/docs/reason-compiler/latest/comparison-to-jsoo.mdx b/pages/docs/reason-compiler/latest/comparison-to-jsoo.mdx
deleted file mode 100644
index 3a69198ff..000000000
--- a/pages/docs/reason-compiler/latest/comparison-to-jsoo.mdx
+++ /dev/null
@@ -1,9 +0,0 @@
-# Comparison to Js_of_ocaml
-
-Js_of_ocaml is a popular compiler which compiles OCaml’s bytecode into JavaScript. It is the inspiration for this project, and has already been under development for several years and is ready for production. ReScript's motivation, like js_of_ocaml, is to unify the ubiquity of the JavaScript platform and the truly sophisticated type system of OCaml.
-
-However, there are a few areas that ReScript approaches differently:
-
-- Js_of_ocaml takes low-level bytecode from OCaml compiler, ReScript takes the high-level rawlambda representation from OCaml compiler.
-- Js_of_ocaml focuses more on existing OCaml ecosystem (OPAM) while ReScript's major goal is to target NPM/Yarn and existing JS workflows.
-- Js_of_ocaml and ReScript have slightly different runtime encoding in several places. For example, ReScript encodes OCaml Array as JS Array while js_of_ocaml requires its index 0 to be of value 0.
diff --git a/pages/docs/reason-compiler/latest/decorators.mdx b/pages/docs/reason-compiler/latest/decorators.mdx
deleted file mode 100644
index b6fb6c58c..000000000
--- a/pages/docs/reason-compiler/latest/decorators.mdx
+++ /dev/null
@@ -1,851 +0,0 @@
-# Decorators
-
-
-
-All available `@bs.`-decorators explained with examples.
-
-
-
-## `[@bs.val]`
-
-`bs.val` allows you to access JS values that are available on the global scope.
-
-For example:
-
-```reason
-[@bs.val] external setTimeout: (unit => unit, int) => int = "setTimeout";
-
-setTimeout(() => Js.log("Hello"), 1000);
-```
-
-
-
-**Tip:** When BS and JS names match, you can use a `""` shorthand:
-
-
-
-```reason
-[@bs.val] external setTimeout : (unit => unit, int) => int = "";
-[@bs.val] external clearTimeout: int => unit = "";
-```
-
-Let's make sure that `clearTimeout` can only get `timeoutID`s returned by `setTimeout`, not any `int`.
-
-Abstract types to the rescue!
-
-```reason
-type timeoutID;
-[@bs.val] external setTimeout: (unit => unit, int) => timeoutID = "";
-[@bs.val] external clearTimeout: timeoutID => unit = "";
-```
-
-What if the value we want to access is on another global object, e.g. `Math.floor`, `Date.now`, or even `location.origin.length`?
-
-That's what `bs.scope` is for. [Check it out!](#bsscope)
-
-## `[@bs.scope]`
-
-`bs.scope` is used with other attributes like [`bs.val`](#bsval) and [`bs.module`](#bsmodule) to access "deep" values.
-
-For example:
-
-```reason
-[@bs.scope "Math"] [@bs.val] external floor: float => int = "";
-[@bs.scope ("location", "origin")] [@bs.val] external originLength: string = "length";
-[@bs.scope "CONSTANTS"] [@bs.module "MyModule"] external initialDays: int = "";
-
-Js.log(floor(3.4));
-Js.log(originLength);
-Js.log(initialDays);
-```
-
-compiles to:
-
-```js
-var MyModule = require("MyModule");
-
-console.log(Math.floor(3.4));
-console.log(location.origin.length);
-console.log(MyModule.CONSTANTS.initialDays);
-```
-
-
-
-**Note:** The order of `bs.*` attributes doesn't matter.
-
-
-
-## `[@bs.get]`
-
-`bs.get` is used to get a property of an object.
-
-For example, say you created a `div` element:
-
-```reason
-type element;
-[@bs.scope "document"] [@bs.val] external createElement: string => element = "";
-
-let div = createElement("div");
-```
-
-How can we access its properties, e.g. `scrollTop`?
-
-Doing this doesn't work:
-
-```reason
-let top = div.scrollTop; // Error: The record field scrollTop can't be found.
-```
-
-That's what `bs.get` is for:
-
-```reason
-[@bs.get] external scrollTop: element => float = "";
-
-let top = scrollTop(div);
-```
-
-which compiles to:
-
-```js
-var top = div.scrollTop;
-```
-
-Note how we defined `scrollTop` as a function that takes an `element`, and BS compiled it to `element.scrollTop`.
-
-## `[@bs.set]`
-
-`bs.set` is used to set a property of an object.
-
-For example, say you created a `div` element:
-
-```reason
-type element;
-[@bs.scope "document"] [@bs.val] external createElement: string => element = "";
-
-let div = createElement("div");
-```
-
-How can we set its properties, e.g. `scrollTop`?
-
-Doing this doesn't work:
-
-```reason
-div.scrollTop = 100; // Error: The record field scrollTop can't be found.
-```
-
-That's what `bs.set` is for:
-
-```reason
-[@bs.set] external setScrollTop: (element, int) => unit = "scrollTop";
-
-setScrollTop(div, 100);
-```
-
-which compiles to:
-
-```js
-div.scrollTop = 100;
-```
-
-Note how we defined `scrollTop` as a function that takes an `element` and a `value`, and BS compiled it to `element.scrollTop = value`.
-
-## `[@bs.send]`
-
-* [`[@bs.send]`](#bssend-1)
-* [`[@bs.send.pipe]`](#bssendpipe)
-
-### `[@bs.send]`
-
-`bs.send` is used to call a function on an object.
-
-For example, say you created a `div` and a `button`:
-
-```reason
-type element;
-[@bs.scope "document"] [@bs.val] external createElement: string => element = "";
-
-let div = createElement("div");
-let button = createElement("button");
-```
-
-How can we append the `button` to the `div`?
-
-Doing this doesn't work:
-
-```reason
-div.appendChild(button); // Error: The record field appendChild can't be found.
-```
-
-That's what `bs.send` is for:
-
-```reason
-[@bs.send] external appendChild: (element, element) => element = "";
-
-appendChild(div, button);
-```
-
-which compiles to:
-
-```js
-div.appendChild(button);
-```
-
-In general, `bs.send` external looks like this:
-
-```reason
-[@bs.send] external fn: (obj, arg1, arg2, arg3, ... , argN) => ...;
-```
-
-You call `fn` like this:
-
-```reason
-fn(obj, arg1, arg2, arg3, ... , argN);
-
-/*
- or equivalently:
-
- obj->fn(arg1, arg2, arg3, ... , argN);
-*/
-```
-
-and BS compiles this to:
-
-```js
-obj.fn(arg1, arg2, arg3, ... , argN);
-```
-
-What if you want the object to come after the arguments like so:
-
-```reason
-fn(arg1, arg2, arg3, ... , argN, obj);
-
-/*
- or equivalently:
-
- obj |> fn(arg1, arg2, arg3, ... , argN);
-*/
-```
-
-That's what `bs.send.pipe` is for.
-
-### `[@bs.send.pipe]`
-
-`bs.send.pipe`, like `bs.send`, is used to call a function on an object.
-
-Unlike `bs.send`, `bs.send.pipe` takes the object as an argument:
-
-```reason
-[@bs.send.pipe: obj] external fn: (arg1, arg2, arg3, ... , argN) => ...;
-```
-
-You call `fn` like this:
-
-```reason
-fn(arg1, arg2, arg3, ... , argN, obj);
-
-/*
- or equivalently:
-
- obj |> fn(arg1, arg2, arg3, ... , argN);
-*/
-```
-
-and BS compiles this to:
-
-```js
-obj.fn(arg1, arg2, arg3, ... , argN);
-```
-
-# `[@bs.module]`
-
-Use `bs.module` when you need to `require` something.
-
-For example:
-
-```reason
-[@bs.module] external uuidv4: unit => string = "uuid/v4";
-
-Js.log(uuidv4());
-```
-
-compiles to:
-
-```js
-var V4 = require("uuid/v4");
-
-console.log(V4());
-```
-
-By passing a string to `bs.module` you can bind to a specific function in the module.
-
-For example:
-
-```reason
-type t;
-[@bs.module "cheerio"] external load: string => t = "";
-
-let q = load("
Hello world
");
-```
-
-compiles to:
-
-```js
-var Cheerio = require("cheerio");
-
-var q = Cheerio.load("Hello world
");
-```
-
-
-
-**Note:** The string provided to `bs.module` can be anything, e.g.: `"./path/to/my_module"`.
-
-
-
-### Dealing with ES6 `export default`
-
-Say that your project has the following `my_module.js` that is compiled with Babel:
-
-```js
-export default "fancy stuff";
-```
-
-You'd bind to it like this:
-
-```reason
-[@bs.module "./path/to/my_module"] external fancyStuff: string = "default";
-
-Js.log(fancyStuff); /* => "fancy stuff" */
-```
-
-This compiles to:
-
-```js
-var My_module = require("./path/to/my_module");
-
-console.log(My_module.default);
-```
-
-## `[@bs.string]`
-
-You can use `bs.string` together with polymorphic variant to constrain function's parameters.
-
-For example:
-
-```reason
-[@bs.module "fs"]
-external readFileSync: (
- ~name: string,
- [@bs.string] [`utf8 | `ascii]
-) => string = "";
-
-readFileSync(~name="data.txt", `utf8);
-```
-
-compiles to:
-
-```js
-var Fs = require("fs");
-
-Fs.readFileSync("data.txt", "utf8");
-```
-
-`bs.string` compiled `` `utf8 `` to the string `"utf8"`.
-
-Now, if we try pass an unknown encoding:
-
-```reason
-readFileSync(~name="data.txt", `binary);
-```
-
-we'll get a compile error.
-
-When your string causes a syntax error in the polymorphic variant (this can happen, for example, when the string starts with a number or contains a special character), use `bs.as`:
-
-```reason
-[@bs.module "fs"]
-external readFileSync: (
- ~name: string,
- [@bs.string] [`utf8 | `ascii | [@bs.as "ucs-2"] `ucs_2]
-) => string = "";
-
-readFileSync(~name="data.txt", `ucs_2);
-```
-
-This compiles to:
-
-```js
-var Fs = require("fs");
-
-Fs.readFileSync("data.txt", "ucs-2");
-```
-
-## `[@bs.int]`
-
-You can use `bs.int` together with polymorphic variant to constrain function's parameters.
-
-For example:
-
-```reason
-[@bs.val]
-external log: (
- ~status: [@bs.int] [[@bs.as 200] `ok | [@bs.as 400] `bad_request | `unauthorized],
- ~message: string
-) => string = "";
-
-log(~status=`unauthorized, ~message="Not allowed");
-```
-
-compiles to:
-
-```js
-log(401, "Not allowed");
-```
-
-`bs.int` compiled `` `unauthorized `` to the number `401`.
-
-Now, if we try pass an unknown status:
-
-```reason
-log(~status=`not_found, ~message="This page is not found");
-```
-
-we'll get a compile error.
-
-Note how we used `bs.as` to better control the numbers that `bs.int` compiles to.
-
-If we omitted all the `bs.as` above, `bs.int` would compile:
-
-- `` `ok `` to `0`
-- `` `bad_request `` to `1`
-- `` `unauthorized `` to `2`
-
-## `[@bs.unwrap]`
-
-Say you have the following JS function:
-
-```js
-function padLeft(padding, str) {
- if (typeof padding === "number") {
- return " ".repeat(padding) + str;
- }
- if (typeof padding === "string") {
- return padding + str;
- }
- throw new Error("Expected padding to be number or string");
-}
-```
-
-Note how `padding` can be either a number or a string.
-
-Here is how you'd bind to this function:
-
-```reason
-[@bs.val]
-external padLeft: (
- [@bs.unwrap] [`Int(int) | `Str(string)],
- string
-) => string = "";
-
-padLeft(`Int(7), "eleven");
-padLeft(`Str("7"), "eleven");
-```
-
-which compiles to:
-
-```js
-padLeft(7, "eleven"); /* => " eleven" */
-padLeft("7", "eleven"); /* => "7eleven" */
-```
-
-Note how `bs.unwrap` simply strips the polymorphic variant constructor (i.e. it unwraps the wrapped value).
-
-Now, any attempts to pass a padding that's not a number or a string, will result in compile error.
-
-```reason
-padLeft(true, "eleven"); /* => compile error */
-padLeft(`Int(7.5), "eleven"); /* => compile error */
-```
-
-Alternatively, you might consider to create two separate functions that bind to the same `padLeft`:
-
-```reason
-[@bs.val] external padLeftWithSpaces: (int, string) => string = "padLeft";
-[@bs.val] external padLeftWithString: (string, string) => string = "padLeft";
-
-padLeftWithSpaces(7, "eleven");
-padLeftWithString("7", "eleven");
-```
-
-The compiled output is the same:
-
-```js
-padLeft(7, "eleven"); /* => " eleven" */
-padLeft("7", "eleven"); /* => "7eleven" */
-```
-
-## `[@bs.new]`
-
-When you need use the JS `new` operator, use `bs.new`.
-
-For example:
-
-```reason
-type t;
-[@bs.new] external createDate: unit => t = "Date";
-
-let date = createDate();
-```
-
-compiles to:
-
-```js
-var date = new Date();
-```
-
-When the object is not available on the global scope and needs importing, add `bs.module`:
-
-```reason
-type t;
-[@bs.module] [@bs.new] external book: unit => t = "Book";
-
-let myBook = book();
-```
-
-compiles to:
-
-```js
-var Book = require("Book");
-var myBook = new Book();
-```
-
-## `[@bs.deriving]`
-
-* [`[@bs.deriving accessors]`](#bsderiving-accessors)
-* [`[@bs.deriving abstract]`](#bsderiving-abstract)
-
-### `[@bs.deriving accessors]`
-
-`[@bs.deriving accessors]` can be used to either generate getter functions for
-a decorated **record type**, or to generate creator functions for constructors of a **variant
-type**.
-
-
-
-**Hint:** Since BuckleScript v7, records are compiled to plain JS objects, so
-you might not need `[@bs.deriving accessors]` for record types. More about
-this [here](/docs/reason-compiler/latest/object#records-as-objects).
-
-
-
-#### Record Accessors
-
-The decorator can be applied to **record types**:
-
-```reason
-[@bs.deriving accessors]
-type person = {
- name: string,
- age: int,
- country: string,
-};
-```
-
-This will create a set of getter functions in the same module scope:
-
-```reason
-let name: (person) => string;
-let age: (person) => int;
-let country: (person) => string;
-```
-
-More details on this can be found
-[here](/docs/manual/v8.0.0/generate-converters-accessors#generate-first-class-accessors-for-record-types).
-
-#### Variant Accessors
-
-For **variant type constructors** we can use the same decorator:
-
-```reason
-[@bs.deriving accessors]
-type action =
- | Add(string)
- | Toggle(int)
- | DeleteOne(int)
- | DeleteAll;
-```
-
-This will create a set of creator functions for every variant constructor in
-the same module scope which will look something like this:
-
-```reason
-let add: (string) => action;
-let toggle: (int) => action;
-let deleteOne: (int) => action;
-let deleteAll: action;
-```
-
-We are now able to use the creator functions safely on the JS side without
-relying on the internal representation of a variant constructor:
-
-```js
-// Note: We assume we've imported the functions from the compiled bs.js file!
-
-const action1 = add("Drink coffee");
-const action2 = toggle(34);
-
-/* Constructors without parameter are just a plain value*/
-const action3 = deleteAll;
-```
-
-More details on this feature can be found
-[here](/docs/manual/v8.0.0/generate-converters-accessors#functions--plain-values-for-variant).
-
-### `[@bs.deriving abstract]`
-
-
-
-**Hint:** Since BuckleScript v7, records are compiled to plain JS objects, so you might not need `[@bs.deriving abstract]`.
-More about this [here](/docs/reason-compiler/latest/object#records-as-objects).
-
-
-
-`bs.deriving abstract` is used to convert a **record type** to the following set of constructs:
-
-- An abstract type representing the "abstract record"
-- A creator function for the new abstract type, where labeled arguments
-represent the attributes of the record
-- A set of setter / getter functions for each record attribute
-
-When using this decorator, the original record type will be removed. You'll
-need to use the newly created functions to create / get / set values of this
-type.
-
-For example let's define a decorated record type `person`:
-
-```reason
-[@bs.deriving abstract]
-type person = {
- name: string,
-
- /* Use the mutable keyword for generating setters */
- mutable age: int
-};
-```
-
-This will expand to the following code within the same module scope:
-
-```reason
-/* The abstract type */
-type person;
-let person: (~name: string, ~age: int) => person;
-
-/* Getters */
-let nameGet: (person) => string;
-let ageGet: (person) => int;
-
-/* Setters (only mutable attributes) */
-let ageSet: (person, int) => unit;
-```
-
-This is how we would use the generated functions:
-
-```reason
-let friend = person(~name="Misha", ~age=20);
-
-Js.log(friend->nameGet); /* => "Misha" */
-
-/* Increase age by 1 via mutation */
-friend->ageSet(friend->ageGet + 1);
-
-Js.log(friend->ageGet); /* => 21 */
-
-/* This will NOT be possible (type is abstract now): */
-let misha = { name: "Misha", age: 20 };
-```
-
-Refer to the [Abstract
-Record Mode](/docs/reason-compiler/latest/object#abstract-record-mode) section
-for a more detailed explanation.
-
-
-## `[@bs.as]`
-
-`bs.as` can be used with [`bs.deriving abstract`](#bsderiving-abstract) or records (BuckleScript v7 and above) to rename fields. This is useful when field names are valid in JS, but not in BS.
-
-For example:
-
-```reason
-[@bs.deriving abstract]
-type button = {
- [@bs.as "type"] type_: string,
- [@bs.as "aria-label"] ariaLabel: string
-};
-
-let submitButton = button(~type_="submit", ~ariaLabel="Submit");
-```
-
-compiles to:
-
-```js
-var submitButton = {
- type: "submit",
- "aria-label": "Submit"
-};
-```
-
-
-
-**Note:** Since BuckleScript 7, `bs.as` can also be used in records:
-
-```reason
-type action = {
- [@bs.as "type"] _type: string,
-};
-```
-
-will be compiled to:
-
-```js
-var action = {
- type: "ADD_USER"
-};
-```
-
-Refer to the [Records as Objects](object.md#records-as-objects) section for a detailed explanation.
-
-
-
-## `[@bs.variadic]`
-
-To model a JS function that takes a variable number of arguments, and all arguments are of the same type, use `bs.variadic`:
-
-```reason
-[@bs.scope "Math"] [@bs.val] [@bs.variadic] external max: array(int) => int = "";
-
-Js.log(max([|5, -2, 6, 1|]));
-```
-
-This compiles to:
-
-```js
-console.log(Math.max(5, -2, 6, 1));
-```
-
-Similarly to [`Function.apply()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply) in JS, `bs.variadic` converts the arguments array in BS to separate arguments on the JS side.
-
-If your function has mandatory arguments, you could use `bs.as` to add them:
-
-```reason
-[@bs.val] [@bs.variadic] external warn: ([@bs.as 404] _, [@bs.as "NOT_FOUND"] _, array(string)) => unit = "log";
-
-warn([||]);
-warn([|"this", "page", "is", "not", "found"|]);
-```
-
-This compiles to:
-
-```js
-log(404, "NOT_FOUND");
-log(404, "NOT_FOUND", "this", "page", "is", "not", "found");
-```
-
-## `[@bs.inline]`
-
-A binding marked with `[@bs.inline]` will tell the compiler to copy (inline) its value in every place the binding is being used.
-This is especially useful for cases where e.g. string constants can't be used as variables, but need to be present as constant values.
-
-Suppose you have a list of allowed colors which are represented as strings in JS:
-
-```reason
-/* Colors.re */
-[@bs.inline]
-let green = "green";
-
-[@bs.inline]
-let red = "red";
-```
-
-You can use them in another module:
-
-```reason
-let allowedColors = [|Colors.green, Colors.red|];
-```
-
-the corresponding values get directly inlined in the JS code:
-
-```js
-var allowedColors = [
- "green",
- "red"
-];
-```
-
-If you omitted the [@bs.inline] statements in the example above, the resulting JS code would look like this:
-
-```js
-var allowedColors = [
- Colors.green,
- Colors.red
-];
-```
-
-which is not zero-cost. Currently `bs.inline` works for `string`, `int` and `bool`. `float` cannot be inlined (yet).
-
-A more advanced, but pretty common use-case is to inline the `NODE_ENV` strings:
-
-```reason
-/* NodeEnv.re */
-[@bs.val] [@bs.scope "process.env"] external env: string = "NODE_ENV";
-
-[@bs.inline]
-let development = "development";
-[@bs.inline]
-let production = "production";
-```
-
-Invoke them in another module:
-
-```reason
-if (NodeEnv.env === NodeEnv.development) {
- Js.log("development");
-}
-```
-
-## `[@bs.meth]`
-
-If you want to call a function of a `Js.t` object, you need to use `bs.meth`, to avoid issues with currying.
-
-For instance, take the following JS object:
-
-```js
-function say (a, b) {
- console.log(a, b);
-};
-
-var john = {
- say
-};
-```
-
-The shape of the `john` object could be typed as follows:
-
-```reason
-type person = {. [@bs.meth] "say": (string, string) => unit};
-[@bs.val] external john: person = "john";
-```
-
-and the `say` method can be called with the JS object access notation (`##`):
-
-```reason
-john##say("hey", "jude");
-```
-
-which compiles to
-
-```js
-john.say("hey", "jude");
-```
-
-When you forget to use `[@bs.meth]` in the function signature, the type checker will error, because it is ensured by the compiler to enforce only fully applied functions in `Js.t` objects.
-
-Refer to the [Object 2](object-2.md#call) section for a more detailed explanation.
diff --git a/pages/docs/reason-compiler/latest/object.mdx b/pages/docs/reason-compiler/latest/object.mdx
deleted file mode 100644
index b28a0939c..000000000
--- a/pages/docs/reason-compiler/latest/object.mdx
+++ /dev/null
@@ -1,419 +0,0 @@
-# Object
-
-JavaScript objects are used for two major purposes:
-
-- As a **hash map** (or "dictionary"), where keys can be dynamically added/removed and where values are of the same type.
-- As a **record**, where fields are fixed (though still maybe sometimes optional) and where values can be of different types.
-
-Correspondingly, BuckleScript works with JS objects in these 2 ways.
-
-## Hash Map Mode
-
-Until recently, where JS finally got proper Map support, objects have been (ab)used as a map. If you use your JS object like this:
-
-- might or might not add/remove arbitrary keys
-- values might or might not be accessed using a dynamic/computed key
-- values are all of the same type
-
-Then use our [`Js.Dict`](/docs/manual/latest/api/js/dict) (for "dictionary") API to bind to that JS object! In this mode, you can do all the metaprogramming you're used to with JS objects: get all keys through `Js.Dict.keys`, get values through `Js.Dict.values`, etc.
-
-### Example
-
-```reason
-/* Create a JS object ourselves */
-let myMap = Js.Dict.empty();
-Js.Dict.set(myMap, "Allison", 10);
-
-/* Use an existing JS object */
-[@bs.val] external studentAges : Js.Dict.t(int) = "student";
-switch (Js.Dict.get(studentAges, "Joe")) {
-| None => Js.log("Joe can't be found")
-| Some(age) => Js.log("Joe is " ++ Belt.Int.toString(age))
-};
-```
-
-Output:
-
-```js
-var Js_dict = require("./stdlib/js_dict.js");
-
-var myMap = { };
-
-myMap["Allison"] = 10;
-
-var match = Js_dict.get(student, "Joe");
-
-if (match !== undefined) {
- console.log("Joe is " + String(match));
-} else {
- console.log("Joe can't be found");
-}
-```
-
-### Design Decisions
-
-You can see that under the hood, a `Js.Dict` is simply backed by a JS object. The entire API uses nothing but ordinary BuckleScript `external`s and wrappers, so the whole API mostly disappears after compilation. It is very convenient when converting files over from JS to BuckleScript.
-
-## Records as Objects
-
-> **Note:** Requires BuckleScript >= v7
-
-In BuckleScript, records are directly compiled into JS objects with the same shape (same attribute names).
-As long as your record doesn't contain any BS specific data structures (variants, lists), it will almost always
-compile to idiomatic JS (this includes nested records etc.):
-
-```reason
-type pet =
- | Dog
- | Cat;
-
-type bloodGroup =
- | A
- | B;
-
-type person = {
- name: string,
- friends: array(string),
- pet: option(pet),
- age: int,
- /* let's pretend our JS expects a null here */
- bloodGroup: Js.Nullable.t(bloodGroup),
-};
-
-let john = {
- name: "John",
- pet: None,
- friends: [|"Anna", "Brad", "Shin"|],
- age: 20,
- bloodGroup: Js.Nullable.null,
-};
-```
-
-will be compiled into:
-
-```js
-var john_friends = /* array */[
- "Anna",
- "Brad",
- "Shin"
-];
-
-var john_bloodGroup = null;
-
-var john = {
- name: "John",
- friends: john_friends,
- pet: undefined,
- age: 20,
- bloodGroup: john_bloodGroup
-};
-
-```
-
-**Please note:**
-- You will still be required to transform variants and lists, so for seamless
- interop, make sure to only use [shared data
- types](/docs/manual/latest/shared-data-types), such as array, string, int, float, etc.
- Alternatively you can use [genType](https://github.com/cristianoc/genType) to
- do automatic convertions between JS <-> BuckleScript values as well.
-- `None` (`option`) values are converted to `undefined`, so if your JS code
- distincts between `null` and `undefined`, use `Js.Nullable.t` instead
-
-
-### Rename fields - [bs.as]
-
-There are often situations where specific record attributes need to have a different name than then resulting JS object.
-The most prominent example would include names like `type`, which are often used for "Action" based patterns in JS, but cannot
-be expressed in BuckleScript, since `type` is a keyword.
-
-To work around that, you can use the `[@bs.as]` attribute to change the target name within the resulting JS object:
-
-```reason
-type action = {
- [@bs.as "type"] _type: string,
-};
-
-let action = { _type: "ADD_USER" };
-```
-
-will be compiled to:
-
-```js
-var action = {
- type: "ADD_USER"
-};
-```
-
-### Mutable fields
-
-You can also use the `mutable` keyword to do your side-effectual work:
-
-```reason
-type person = {
- mutable name: string
-};
-
-let p = {name: "Franz"};
-p.name = "Sabine";
-```
-
-which will translate cleanly to:
-
-```js
-var p = {
- name: "Franz"
-};
-
-p.name = "Sabine";
-
-```
-
-
-## Abstract Record Mode
-
-> **Note**: For BuckleScript >= v7, we recommend using the plain [Record as Objects](#records-as-objects) mechanic.
-> This feature might still be useful for certain scenarios, but the ergonomics might be worse
-
-If your JS object:
-
-- has a known, fixed set of fields
-- might or might not contain values of different types
-
-Then you're really using it like a "record" in most other languages. For example, think of the difference of use-case and intent between the object `{"John": 10, "Allison": 20, "Jimmy": 15}` and `{name: "John", age: 10, job: "CEO"}`. The former case would be the aforementioned "hash map mode". The latter would be "abstract record mode", which in BuckleScript is modeled with the `bs.deriving abstract` feature:
-
-```reason
-[@bs.deriving abstract]
-type person = {
- name: string,
- age: int,
- job: string,
-};
-
-[@bs.val] external john : person = "john";
-```
-
-**Note**: the `person` type is **not** a record! It's a record-looking type that uses the record's syntax and type-checking. The `bs.deriving abstract` annotation turns it into an "abstract type" (aka you don't know what the actual value's shape).
-
-### Creation
-
-You don't have to bind to an existing `person` object from the JS side. You can also create such `person` JS object from BuckleScript's side.
-
-Since `bs.deriving abstract` turns the above `person` record into an abstract type, you can't directly create a person record as you would usually. This doesn't work: `{name: "Joe", age: 20, job: "teacher"}`.
-
-Instead, you'd use the **creation function** of the same name as the record type, implicitly generated by the `bs.deriving abstract` annotation:
-
-```reason
-let joe = person(~name="Joe", ~age=20, ~job="teacher")
-```
-
-Output:
-
-```js
-var joe = {
- name: "Joe",
- age: 20,
- job: "teacher"
-};
-```
-
-Look ma, no runtime cost!
-
-#### Rename Fields
-
-Sometimes you might be binding to a JS object with field names that are invalid in BuckleScript/Reason. Two examples would be `{type: "foo"}` (reserved keyword in BS/Reason) and `{"aria-checked": true}`. Choose a valid field name then use `[@bs.as]` to circumvent this:
-
-```reason
-[@bs.deriving abstract]
-type data = {
- [@bs.as "type"] type_: string,
- [@bs.as "aria-label"] ariaLabel: string,
-};
-
-let d = data(~type_="message", ~ariaLabel="hello");
-```
-
-Output:
-
-```js
-var d = {
- type: "message",
- "aria-label": "hello"
-};
-```
-
-#### Optional Labels
-
-You can omit fields during the creation of the object:
-
-```reason
-[@bs.deriving abstract]
-type person = {
- [@bs.optional] name: string,
- age: int,
- job: string,
-};
-
-let joe = person(~age=20, ~job="teacher", ());
-```
-
-**Note** that the `[@bs.optional]` tag turned the `name` field optional. Merely typing `name` as `option(string)` wouldn't work.
-
-**Note**: now that your creation function contains optional fields, we mandate an unlabeled `()` at the end to indicate that [you've finished applying the function](/docs/manual/latest/function.html#optional-labeled-arguments).
-
-### Accessors
-
-Again, since `bs.deriving abstract` hides the actual record shape, you can't access a field using e.g. `joe.age`. We remediate this by generating getter and setters.
-
-#### Read
-
-One getter function is generated per `bs.deriving abstract` record type field. In the above example, you'd get 3 functions: `nameGet`, `ageGet`, `jobGet`. They take in a `person` value and return `string`, `int`, `string` respectively:
-
-```reason
-let twenty = ageGet(joe)
-```
-
-Alternatively, you can use the [Pipe](/docs/manual/latest/pipe.md) feature in a later section for a nicer-looking access syntax:
-
-```reason
-let twenty = joe->ageGet
-```
-
-If you prefer shorter names for the getter functions, [we also support a 'light' setting](https://bucklescript.github.io/blog/2019/03/21/release-5-0):
-
-```reason
-[@bs.deriving {abstract: light}]
-type person = {
- name: string,
- age: int,
-};
-
-let joe = person(~name="Joe", ~age=20);
-let joeName = name(joe);
-```
-
-The getter functions will now have the same names as the object fields themselves.
-
-#### Write
-
-A `bs.deriving abstract` value is immutable by default. To mutate such value, you need to first mark one of the abstract record field as `mutable`, the same way you'd mark a normal record as mutable:
-
-```reason
-[@bs.deriving abstract]
-type person = {
- name: string,
- mutable age: int,
- job: string,
-};
-```
-
-Then, a setter of the name `ageSet` will be generated. Use it like so:
-
-```reason
-let joe = person(~name="Joe", ~age=20, ~job="teacher");
-ageSet(joe, 21);
-```
-
-Alternatively, with the Pipe First syntax:
-
-```reason
-joe->ageSet(21)
-```
-
-### Methods
-
-You can attach arbitrary methods onto a type (_any_ type, as a matter of fact. Not just `bs.deriving abstract` record types). See [Object Method](/docs/manual/latest/bind-to-js-function.md#object-method) in the function section later.
-
-### Tips & Tricks
-
-You can leverage `bs.deriving abstract` for finer-grained access control.
-
-#### Mutability
-
-You can mark a field as mutable in the implementation (`ml`/`re`) file, while _hiding_ such mutability in the interface file:
-
-```reason
-/* test.re */
-[@bs.deriving abstract]
-type cord = {
- [@bs.optional] mutable x: int,
- y: int,
-};
-```
-
-```reason
-/* test.rei */
-[@bs.deriving abstract]
-type cord = {
- [@bs.optional] x: int,
- y: int,
-};
-```
-
-Tada! Now you can mutate inside your own file as much as you want, and prevent others from doing so!
-
-#### Hide the Creation Function
-
-Mark the record as `private` to disable the creation function:
-
-```reason
-[@bs.deriving abstract]
-type cord = pri {
- [@bs.optional] x: int,
- y: int,
-};
-```
-
-The accessors are still there, but you can no longer create such data structure. Great for binding to a JS object while preventing others from creating more such object!
-
-#### Use submodules to prevent naming collisions and binding shadowing
-
-Oftentimes you will have multiple abstract types with similar attributes. Since
-BuckleScript will expand all abstract getter, setter and creation functions in the
-same scope where the type is defined, you will eventually run into value shadowing problems.
-
-**For example:**
-
-```reason
-[@bs.deriving abstract]
-type person = {name: string};
-
-[@bs.deriving abstract]
-type cat = {
- name: string,
- isLazy: bool,
-};
-
-let person = person(~name="Alice");
-
-/* Error: This expression has type person but an expression was expected
- of type cat */
-person->nameGet();
-```
-
-To get around this issue, you can use modules to group a type with its related
-functions and later use them via local open statements:
-
-```reason
-module Person = {
- [@bs.deriving abstract]
- type t = {name: string};
-};
-
-module Cat = {
- [@bs.deriving abstract]
- type t = {
- name: string,
- isLazy: bool,
- };
-};
-
-let person = Person.t(~name="Alice");
-let cat = Cat.t(~name="Snowball", ~isLazy=true);
-
-/* We can use each nameGet function separately now */
-let shoutPersonName = Person.(person->nameGet->Js.String.toUpperCase);
-
-/* Note how we use a local open Cat.([some expression]) to
- get access to Cat's nameGet function */
-let whisperCatName = Cat.(cat->nameGet->Js.String.toLowerCase);
-```
diff --git a/pages/docs/reason-compiler/latest/use-existing-ocaml-libraries.mdx b/pages/docs/reason-compiler/latest/use-existing-ocaml-libraries.mdx
deleted file mode 100644
index b1a3a2054..000000000
--- a/pages/docs/reason-compiler/latest/use-existing-ocaml-libraries.mdx
+++ /dev/null
@@ -1,58 +0,0 @@
-# Use Existing OCaml Libraries
-
-> This section is reserved for advanced usages. Usually, you'd pick an OCaml/Reason library that's already configured to work with our higher-level build system `bsb` (aka has a `bsconfig.json`). If not, you'd usually add a `bsconfig.json` to it. But if you want to directly use an OCaml package that's not part of the npm workflow, or are building some quirky infra with BuckleScript, keep reading!
-
-This guide is also a small walkthrough of how `bsb` works under the hood.
-
-## Built in NPM support
-
-### Build an OCaml Library as a NPM Package
-
-**Note**: this section might be slightly stale. If any of the steps aren't working, please file us an issue! Thanks.
-
-**We highly recommend** you try this endeavour on a dependency-less library first. It'd avoid lots of trouble.
-
-BuckleScript's compiler, `bsc`, extends the OCaml compiler options with several flags to provide a better experience for NPM users.
-
-In general, you are expected to see two kinds of build artifacts: the generated JS files and metadata that your OCaml dependencies rely on.
-
-Since CommonJS has no namespaces, to allow JS files to live in different directories, we have a flag
-
-```sh
-bsc.exe -bs-package-name $npm_package_name -bs-package-output modulesystem:path/to/your/js/dir -c a.ml
-```
-
-By passing this flag, `bsc.exe` will store your `package_name` and relative path to `package.json` in `.cmj` files. It will also generate JS files in the directory you specified. You can, and are encouraged to, store JavaScript files in a hierarchical directory.
-
-For the binary artifacts (Note that this is not necessary if you only want your libraries to be consumed by JS developers, and it has benefit since end users don’t need these binary data any more), the convention is to store all `*.cm` data in a *single* directory `package.json/lib/ocaml` and Javascript files in a *hierachical* directory like `package.json/lib/js`.
-
-### Use an OCaml Library as a NPM Package
-
-If you follow the layout convention above, using an OCaml package is pretty straightforward:
-
-```sh
-bsc.exe -I path/to/ocaml/package/installed -c a.ml
-```
-
-### Together
-
-Your command line would be like this:
-
-```sh
-bsc.exe -I path/to/ocaml/package1/installed -I path/to/ocaml/package2/installed -bs-package-name $npm_package_name -bs-package-output commonjs:path/to/lib/js/ -c a.ml
-```
-
-### Examples
-
-You can see a more elaborate `bsc` setup like so:
-
-```sh
-bsb -init dummy-project
-cd dummy-project
-npm run build
-cat lib/bs/build.ninja
-```
-
-The [Ninja](https://ninja-build.org) file, generated by `bsb`, describes the exact steps needed to build a trivial project using `bsc`.
-
-Additionally, please consult https://github.com/chenglou/intro-to-reason-compilation, which covers the lowest-level [Reason](https://reasonml.github.io) + BuckleScript compilation mechanisms.