diff --git a/docs/recursive-type-restriction.md b/docs/recursive-type-restriction.md
new file mode 100644
index 0000000..eb9b212
--- /dev/null
+++ b/docs/recursive-type-restriction.md
@@ -0,0 +1,59 @@
+# Recursive type restriction
+
+## Motivation
+
+Luau supports recursive type aliases, but with an important restriction:
+users can declare functions of recursive types, such as:
+```lua
+ type Tree = { data: a, children: {Tree} }
+```
+but *not* recursive type functions, such as:
+```lua
+ type Weird = { data: a, children: Weird<{a}> }
+```
+If types such as `Weird` were allowed, they would have infinite unfoldings for example:
+```lua
+ Weird = { data: number, children: Weird<{number}> }`
+ Weird<{number}> = { data: {number}, children: Weird<{{number}}> }
+ Weird<{{number}}> = { data: {{number}}, children: Weird<{{{number}}}> }
+ ...
+```
+
+Currently Luau has this restriction, but does not enforce it, and instead
+produces unexpected types, which can result in free types leaking into
+the module exports.
+
+## Design
+
+To enforce the restriction that recursive types aliases produce functions of
+recursive types, we require that in any recursive type alias defining `T`,
+in any recursive use of `T`, we have that `gs` and `Us` are equal.
+
+This allows types such as:
+```lua
+ type Tree = { data: a, children: {Tree} }
+```
+but *not*:
+```lua
+ type Weird = { data: a, children: Weird<{a}> }
+```
+since in the recursive use `a` is not equal to `{a}`.
+
+This restriction applies to mutually recursive types too.
+
+## Drawbacks
+
+This restriction bans some type declarations which do not produce infinite unfoldings,
+such as:
+```lua
+ type WeirdButFinite = { data: a, children: WeirdButFinite }
+```
+This restriction is stricter than TypeScript, which allows programs such as:
+```typescript
+interface Foo { x: Foo[]; y: a; }
+let x: Foo = { x: [], y: 37 }
+```
+
+## Alternatives
+
+We could adopt a solution more like TypeScript's, which is to lazily rather than eagerly instantiate types.