diff --git a/data/sidebar_manual_latest.json b/data/sidebar_manual_latest.json
index 3d42984c2..9b516a776 100644
--- a/data/sidebar_manual_latest.json
+++ b/data/sidebar_manual_latest.json
@@ -33,6 +33,9 @@
"unboxed",
"reserved-keywords"
],
+ "Advanced Features": [
+ "extensible-variant"
+ ],
"JavaScript Interop": [
"embed-raw-javascript",
"shared-data-types",
diff --git a/pages/docs/manual/latest/extensible-variant.mdx b/pages/docs/manual/latest/extensible-variant.mdx
new file mode 100644
index 000000000..0569bd6b0
--- /dev/null
+++ b/pages/docs/manual/latest/extensible-variant.mdx
@@ -0,0 +1,75 @@
+---
+title: "Extensible Variant"
+description: "Extensible Variants in ReScript"
+canonical: "/docs/manual/latest/extensible-variant"
+---
+
+# Extensible Variant
+
+Variant types are usually constrained to a fixed set of constructors. There may be very rare cases where you still want to be able to add constructors to a variant type even after its initial type declaration. For this, we offer extensible variant types.
+
+## Definition and Usage
+
+
+
+```res example
+type t = ..
+
+type t += Other
+
+type t +=
+ | Point(float, float)
+ | Line(float, float, float, float)
+```
+```js
+var Caml_exceptions = require("./stdlib/caml_exceptions.js");
+
+var Other = Caml_exceptions.create("Playground.Other");
+
+var Point = Caml_exceptions.create("Playground.Point");
+
+var Line = Caml_exceptions.create("Playground.Line");
+```
+
+
+
+The `..` in the type declaration above defines an extensible variant `type t`. The `+=` operator is then used to add constructors to the given type.
+
+**Note:** Don't forget the leading `type` keyword when using the `+=` operator!
+
+## Pattern Matching Caveats
+
+Extensible variants are open-ended, so the compiler will not be able to exhaustively pattern match all available cases. You will always need to provide a default `_` case for every `switch` expression.
+
+
+
+
+
+```res
+let print = v =>
+ switch v {
+ | Point(x, y) => Js.log2("Point", (x, y))
+ | Line(ax, ay, bx, by) => Js.log2("Line", (ax, ay, bx, by))
+ | Other
+ | _ => Js.log("Other")
+ }
+```
+```js
+function print(v) {
+ if (v.RE_EXN_ID === Point) {
+ console.log("Point", [v._1, v._2]);
+ } else if (v.RE_EXN_ID === Line) {
+ console.log("Line", [v._1, v._2, v._3, v._4]);
+ } else {
+ console.log("Other");
+ }
+}
+```
+
+
+
+## Tips & Tricks
+
+**Fun fact:** In ReScript, [exceptions](./exception) are actually extensible variants under the hood, so `exception UserError(string)` is equivalent to `type exn += UserError(string)`. It's one of the very few use-case where extensible variants make sense.
+
+We usually recommend sticking with common [variants](./variant) as much as possible to reap the benefits of exhaustive pattern matching.
\ No newline at end of file