diff --git a/CHANGELOG.md b/CHANGELOG.md
index e957cdf72..8ab615cee 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,6 +18,7 @@
 - Code Lenses for functions (experimetal). `rescript.settings.codeLens: true`. Turned off by default. https://github.com/rescript-lang/rescript-vscode/pull/513
 - Markdown code blocks tagged as `rescript` now get basic syntax highlighting. https://github.com/rescript-lang/rescript-vscode/pull/97
 - Hover support for doc comments on v10 compiler `/** this is a doc comment */`
+- Code action to convert type to module. https://github.com/rescript-lang/rescript-vscode/issues/430
 
 #### :bug: Bug Fix
 
diff --git a/analysis/src/CodeActions.ml b/analysis/src/CodeActions.ml
index 844e25bce..9c5fd3125 100644
--- a/analysis/src/CodeActions.ml
+++ b/analysis/src/CodeActions.ml
@@ -5,13 +5,4 @@ let stringifyCodeActions codeActions =
   Printf.sprintf {|%s|}
     (codeActions |> List.map Protocol.stringifyCodeAction |> Protocol.array)
 
-let make ~title ~kind ~uri ~newText ~range =
-  {
-    Protocol.title;
-    codeActionKind = kind;
-    edit =
-      {
-        documentChanges =
-          [{textDocument = {version = None; uri}; edits = [{newText; range}]}];
-      };
-  }
+let make ~title ~kind ~edit = {Protocol.title; codeActionKind = kind; edit}
diff --git a/analysis/src/Commands.ml b/analysis/src/Commands.ml
index 5fcbca9ac..bc248473c 100644
--- a/analysis/src/Commands.ml
+++ b/analysis/src/Commands.ml
@@ -175,73 +175,9 @@ let references ~path ~pos ~debug =
 
 let rename ~path ~pos ~newName ~debug =
   let result =
-    match Cmt.fullFromPath ~path with
+    match Rename.command ~path ~pos ~newName ~debug with
+    | Some workspaceEdit -> workspaceEdit |> Protocol.stringifyWorkspaceEdit
     | None -> Protocol.null
-    | Some full -> (
-      match References.getLocItem ~full ~pos ~debug with
-      | None -> Protocol.null
-      | Some locItem ->
-        let allReferences = References.allReferencesForLocItem ~full locItem in
-        let referencesToToplevelModules =
-          allReferences
-          |> Utils.filterMap (fun {References.uri = uri2; locOpt} ->
-                 if locOpt = None then Some uri2 else None)
-        in
-        let referencesToItems =
-          allReferences
-          |> Utils.filterMap (function
-               | {References.uri = uri2; locOpt = Some loc} -> Some (uri2, loc)
-               | {locOpt = None} -> None)
-        in
-        let fileRenames =
-          referencesToToplevelModules
-          |> List.map (fun uri ->
-                 let path = Uri.toPath uri in
-                 let dir = Filename.dirname path in
-                 let newPath =
-                   Filename.concat dir (newName ^ Filename.extension path)
-                 in
-                 let newUri = Uri.fromPath newPath in
-                 Protocol.
-                   {
-                     oldUri = uri |> Uri.toString;
-                     newUri = newUri |> Uri.toString;
-                   })
-        in
-        let textDocumentEdits =
-          let module StringMap = Misc.StringMap in
-          let textEditsByUri =
-            referencesToItems
-            |> List.map (fun (uri, loc) -> (Uri.toString uri, loc))
-            |> List.fold_left
-                 (fun acc (uri, loc) ->
-                   let textEdit =
-                     Protocol.
-                       {range = Utils.cmtLocToRange loc; newText = newName}
-                   in
-                   match StringMap.find_opt uri acc with
-                   | None -> StringMap.add uri [textEdit] acc
-                   | Some prevEdits ->
-                     StringMap.add uri (textEdit :: prevEdits) acc)
-                 StringMap.empty
-          in
-          StringMap.fold
-            (fun uri edits acc ->
-              let textDocumentEdit =
-                Protocol.{textDocument = {uri; version = None}; edits}
-              in
-              textDocumentEdit :: acc)
-            textEditsByUri []
-        in
-        let fileRenamesString =
-          fileRenames |> List.map Protocol.stringifyRenameFile
-        in
-        let textDocumentEditsString =
-          textDocumentEdits |> List.map Protocol.stringifyTextDocumentEdit
-        in
-        "[\n"
-        ^ (fileRenamesString @ textDocumentEditsString |> String.concat ",\n")
-        ^ "\n]")
   in
   print_endline result
 
@@ -383,15 +319,20 @@ let test ~path =
             |> List.iter (fun {Protocol.title; edit = {documentChanges}} ->
                    Printf.printf "Hit: %s\n" title;
                    documentChanges
-                   |> List.iter (fun {Protocol.edits} ->
-                          edits
-                          |> List.iter (fun {Protocol.range; newText} ->
-                                 let indent =
-                                   String.make range.start.character ' '
-                                 in
-                                 Printf.printf "%s\nnewText:\n%s<--here\n%s%s\n"
-                                   (Protocol.stringifyRange range)
-                                   indent indent newText)))
+                   |> List.iter
+                        (fun (documentChange : Protocol.documentChange) ->
+                          match documentChange with
+                          | TextDocumentEdit {edits} ->
+                            edits
+                            |> List.iter (fun {Protocol.range; newText} ->
+                                   let indent =
+                                     String.make range.start.character ' '
+                                   in
+                                   Printf.printf
+                                     "%s\nnewText:\n%s<--here\n%s%s\n"
+                                     (Protocol.stringifyRange range)
+                                     indent indent newText)
+                          | _ -> ()))
           | "dia" -> diagnosticSyntax ~path
           | "hin" ->
             let line_start = 0 in
diff --git a/analysis/src/Protocol.ml b/analysis/src/Protocol.ml
index a1440aa85..3f56ae125 100644
--- a/analysis/src/Protocol.ml
+++ b/analysis/src/Protocol.ml
@@ -41,13 +41,17 @@ type textDocumentEdit = {
   edits: textEdit list;
 }
 
-type codeActionEdit = {documentChanges: textDocumentEdit list}
+type documentChange =
+  | TextDocumentEdit of textDocumentEdit
+  | RenameFile of renameFile
+
+type workspaceEdit = {documentChanges: documentChange list}
 type codeActionKind = RefactorRewrite
 
 type codeAction = {
   title: string;
   codeActionKind: codeActionKind;
-  edit: codeActionEdit;
+  edit: workspaceEdit;
 }
 
 let null = "null"
@@ -133,14 +137,19 @@ let codeActionKindToString kind =
   match kind with
   | RefactorRewrite -> "refactor.rewrite"
 
-let stringifyCodeActionEdit cae =
+let stringifyWorkspaceEdit we =
   Printf.sprintf {|{"documentChanges": %s}|}
-    (cae.documentChanges |> List.map stringifyTextDocumentEdit |> array)
+    (we.documentChanges
+    |> List.map (fun documentChange ->
+           match documentChange with
+           | TextDocumentEdit textEdit -> textEdit |> stringifyTextDocumentEdit
+           | RenameFile renameFile -> renameFile |> stringifyRenameFile)
+    |> array)
 
 let stringifyCodeAction ca =
   Printf.sprintf {|{"title": "%s", "kind": "%s", "edit": %s}|} ca.title
     (codeActionKindToString ca.codeActionKind)
-    (ca.edit |> stringifyCodeActionEdit)
+    (ca.edit |> stringifyWorkspaceEdit)
 
 let stringifyHint hint =
   Printf.sprintf
diff --git a/analysis/src/Rename.ml b/analysis/src/Rename.ml
new file mode 100644
index 000000000..231e538e0
--- /dev/null
+++ b/analysis/src/Rename.ml
@@ -0,0 +1,58 @@
+let command ~path ~pos ~newName ~debug =
+  match Cmt.fullFromPath ~path with
+  | None -> None
+  | Some full -> (
+    match References.getLocItem ~full ~pos ~debug with
+    | None -> None
+    | Some locItem ->
+      let allReferences = References.allReferencesForLocItem ~full locItem in
+      let referencesToToplevelModules =
+        allReferences
+        |> Utils.filterMap (fun {References.uri = uri2; locOpt} ->
+               if locOpt = None then Some uri2 else None)
+      in
+      let referencesToItems =
+        allReferences
+        |> Utils.filterMap (function
+             | {References.uri = uri2; locOpt = Some loc} -> Some (uri2, loc)
+             | {locOpt = None} -> None)
+      in
+      let fileRenames =
+        referencesToToplevelModules
+        |> List.map (fun uri ->
+               let path = Uri.toPath uri in
+               let dir = Filename.dirname path in
+               let newPath =
+                 Filename.concat dir (newName ^ Filename.extension path)
+               in
+               let newUri = Uri.fromPath newPath in
+               Protocol.RenameFile
+                 {oldUri = uri |> Uri.toString; newUri = newUri |> Uri.toString})
+      in
+      let textDocumentEdits =
+        let module StringMap = Misc.StringMap in
+        let textEditsByUri =
+          referencesToItems
+          |> List.map (fun (uri, loc) -> (Uri.toString uri, loc))
+          |> List.fold_left
+               (fun acc (uri, loc) ->
+                 let textEdit =
+                   Protocol.{range = Utils.cmtLocToRange loc; newText = newName}
+                 in
+                 match StringMap.find_opt uri acc with
+                 | None -> StringMap.add uri [textEdit] acc
+                 | Some prevEdits ->
+                   StringMap.add uri (textEdit :: prevEdits) acc)
+               StringMap.empty
+        in
+        StringMap.fold
+          (fun uri edits acc ->
+            let textDocumentEdit =
+              Protocol.TextDocumentEdit
+                {textDocument = {uri; version = None}; edits}
+            in
+            textDocumentEdit :: acc)
+          textEditsByUri []
+      in
+      let documentChanges = fileRenames @ textDocumentEdits in
+      Some Protocol.{documentChanges})
diff --git a/analysis/src/Xform.ml b/analysis/src/Xform.ml
index a402ca92e..6616fc873 100644
--- a/analysis/src/Xform.ml
+++ b/analysis/src/Xform.ml
@@ -110,9 +110,20 @@ module IfThenElse = struct
     | Some newExpr ->
       let range = rangeOfLoc newExpr.pexp_loc in
       let newText = printExpr ~range newExpr in
+      let uri = Uri.fromPath path |> Uri.toString in
       let codeAction =
         CodeActions.make ~title:"Replace with switch" ~kind:RefactorRewrite
-          ~uri:path ~newText ~range
+          ~edit:
+            {
+              documentChanges =
+                [
+                  TextDocumentEdit
+                    {
+                      textDocument = {version = None; uri};
+                      edits = [{newText; range}];
+                    };
+                ];
+            }
       in
       codeActions := codeAction :: !codeActions
 end
@@ -174,9 +185,20 @@ module AddBracesToFn = struct
     | Some newStructureItem ->
       let range = rangeOfLoc newStructureItem.pstr_loc in
       let newText = printStructureItem ~range newStructureItem in
+      let uri = Uri.fromPath path |> Uri.toString in
       let codeAction =
         CodeActions.make ~title:"Add braces to function" ~kind:RefactorRewrite
-          ~uri:path ~newText ~range
+          ~edit:
+            {
+              documentChanges =
+                [
+                  TextDocumentEdit
+                    {
+                      textDocument = {version = None; uri};
+                      edits = [{newText; range}];
+                    };
+                ];
+            }
       in
       codeActions := codeAction :: !codeActions
 end
@@ -249,14 +271,144 @@ module AddTypeAnnotation = struct
               ( rangeOfLoc locItem.loc,
                 "(" ^ name ^ ": " ^ (typ |> Shared.typeToString) ^ ")" )
           in
+          let uri = Uri.fromPath path |> Uri.toString in
           let codeAction =
             CodeActions.make ~title:"Add type annotation" ~kind:RefactorRewrite
-              ~uri:path ~newText ~range
+              ~edit:
+                {
+                  documentChanges =
+                    [
+                      TextDocumentEdit
+                        {
+                          textDocument = {version = None; uri};
+                          edits = [{newText; range}];
+                        };
+                    ];
+                }
           in
           codeActions := codeAction :: !codeActions
         | _ -> ()))
 end
 
+module TypeToModule = struct
+  (* Convert type definition into its own module *)
+  let mkIterator ~pos ~result ~newTypeName =
+    let changeTypeDecl (typ : Parsetree.type_declaration) ~txt =
+      let manifest = typ.ptype_manifest in
+      Ast_helper.Type.mk
+        {txt; loc = typ.ptype_name.loc}
+        ~loc:typ.ptype_loc ~attrs:typ.ptype_attributes ~params:typ.ptype_params
+        ~cstrs:typ.ptype_cstrs ~kind:typ.ptype_kind ~priv:typ.ptype_private
+        ?manifest
+    in
+
+    let structure_item (iterator : Ast_iterator.iterator)
+        (si : Parsetree.structure_item) =
+      match si.pstr_desc with
+      | Pstr_type (Nonrecursive, firstypeDec :: rest)
+        when Loc.hasPos ~pos si.pstr_loc ->
+        let loc = si.pstr_loc in
+        let firsLetterOfModule =
+          String.get firstypeDec.ptype_name.txt 0
+          |> Char.uppercase_ascii |> String.make 1
+        in
+        let restName =
+          String.sub firstypeDec.ptype_name.txt 1
+            (String.length firstypeDec.ptype_name.txt - 1)
+        in
+        let modName = firsLetterOfModule ^ restName in
+        let newFistType = changeTypeDecl firstypeDec ~txt:newTypeName in
+        let restStrucTypes =
+          Ast_helper.Str.type_ ~loc Nonrecursive ([newFistType] @ rest)
+        in
+        let pmb_expr = Ast_helper.Mod.structure ~loc [restStrucTypes] in
+        let mod_expr =
+          Parsetree.Pstr_module
+            {
+              pmb_name = {txt = modName; loc};
+              pmb_expr;
+              pmb_attributes = [];
+              pmb_loc = loc;
+            }
+        in
+        let processTypeKind (typeDec : Parsetree.type_declaration) =
+          match typeDec.ptype_kind with
+          | Ptype_record [{pld_name = {loc; txt}}; _] -> Some (loc, txt)
+          | Ptype_variant [{pcd_name = {loc; txt}}; _] -> Some (loc, txt)
+          | _ -> None
+        in
+        let references =
+          let referencesInfo =
+            [firstypeDec] @ rest |> List.filter_map processTypeKind
+          in
+          [(firstypeDec.ptype_name.loc, newTypeName)] @ referencesInfo
+        in
+        result := Some (Ast_helper.Str.mk ~loc mod_expr, references, modName);
+        Ast_iterator.default_iterator.structure_item iterator si
+      | _ -> ()
+    in
+    {Ast_iterator.default_iterator with structure_item}
+
+  let xform ~path ~pos ~codeActions ~printStructureItem structure ~debug =
+    let result = ref None in
+    let newTypeName = "t" in
+    let iterator = mkIterator ~pos ~result ~newTypeName in
+    iterator.structure iterator structure;
+    match !result with
+    | None -> ()
+    | Some (newStructureItem, references, modName) ->
+      let range = rangeOfLoc newStructureItem.pstr_loc in
+      let newText = printStructureItem ~range newStructureItem in
+      let uri = Uri.fromPath path |> Uri.toString in
+      let typeToModuleEdit =
+        Protocol.TextDocumentEdit
+          {textDocument = {version = None; uri}; edits = [{newText; range}]}
+      in
+      (* Before apply code action find all references and rename with new name *)
+      let relatedChanges =
+        references
+        |> List.filter_map (fun (loc, txt) ->
+               let range = rangeOfLoc loc in
+               let newName = modName ^ "." ^ txt in
+               match
+                 Rename.command ~path
+                   ~pos:(range.start.line, range.start.character)
+                   ~newName ~debug
+               with
+               | Some workspaceEdit ->
+                 let result =
+                   workspaceEdit.documentChanges
+                   |> List.map
+                        (fun (documentChange : Protocol.documentChange) ->
+                          match documentChange with
+                          | TextDocumentEdit textEdit ->
+                            let textDocument = textEdit.textDocument in
+                            let edits =
+                              if textDocument.uri = uri then
+                                textEdit.edits
+                                |> List.filter
+                                     (fun (textEdit : Protocol.textEdit) ->
+                                       (* Ignore some text edit because it refers to the type that will be moved to its own module *)
+                                       textEdit.range <> range)
+                              else textEdit.edits
+                            in
+                            Protocol.TextDocumentEdit {textDocument; edits}
+                          | _ -> documentChange)
+                 in
+                 Some result
+               | None -> None)
+        |> List.flatten
+      in
+      let edit : Protocol.workspaceEdit =
+        {documentChanges = [typeToModuleEdit] @ relatedChanges}
+      in
+      let codeAction =
+        CodeActions.make ~title:"Move type definition into its own module"
+          ~kind:RefactorRewrite ~edit
+      in
+      codeActions := codeAction :: !codeActions
+end
+
 let indent n text =
   let spaces = String.make n ' ' in
   let len = String.length text in
@@ -310,5 +462,7 @@ let extractCodeActions ~path ~pos ~currentFile ~debug =
     AddTypeAnnotation.xform ~path ~pos ~full ~structure ~codeActions ~debug;
     IfThenElse.xform ~pos ~codeActions ~printExpr ~path structure;
     AddBracesToFn.xform ~pos ~codeActions ~path ~printStructureItem structure;
+    TypeToModule.xform ~path ~pos ~codeActions ~printStructureItem structure
+      ~debug;
     !codeActions
   | _ -> []
diff --git a/analysis/tests/src/Xform.res b/analysis/tests/src/Xform.res
index 52baad9d8..15ed72964 100644
--- a/analysis/tests/src/Xform.res
+++ b/analysis/tests/src/Xform.res
@@ -65,3 +65,42 @@ let bar = () => {
   }
   Inner.foo(1)
 }
+
+type readState = New | Unread | Read
+//^xfm
+
+type refState = readState
+
+type account =
+  | None
+  | Instagram(string)
+  | Facebook(string, int)
+//^xfm
+
+type person = {
+  "age": int,
+  "name": string
+}
+//^xfm
+
+type user = {
+  name: string,
+  age: int,
+} and response = Yes | No
+//^xfm
+
+type myType = This | That
+//^xfm
+
+let fun1 = (x: myType) => x
+
+let fun2 = b => b ? This : That
+
+let fun3 = b => b ? {name: "Lhs", age: 2} : {name: "Rhs", age: 3}
+
+let fun4 = b => b ? Yes : No
+
+let me: person = {
+  "age": 5,
+  "name": "Big ReScript"
+}
\ No newline at end of file
diff --git a/analysis/tests/src/expected/Cross.res.txt b/analysis/tests/src/expected/Cross.res.txt
index b045e8a02..013485cfa 100644
--- a/analysis/tests/src/expected/Cross.res.txt
+++ b/analysis/tests/src/expected/Cross.res.txt
@@ -18,18 +18,15 @@ References src/Cross.res 9:31
 ]
 
 Rename src/Cross.res 18:13 RenameWithInterfacePrime
-[
-{
+{"documentChanges": [{
   "kind": "rename",
   "oldUri": "RenameWithInterface.resi",
   "newUri": "RenameWithInterfacePrime.resi"
-},
-{
+}, {
   "kind": "rename",
   "oldUri": "RenameWithInterface.res",
   "newUri": "RenameWithInterfacePrime.res"
-},
-{
+}, {
   "textDocument": {
   "version": null,
   "uri": "Cross.res"
@@ -41,12 +38,10 @@ Rename src/Cross.res 18:13 RenameWithInterfacePrime
   "range": {"start": {"line": 21, "character": 8}, "end": {"line": 21, "character": 27}},
   "newText": "RenameWithInterfacePrime"
   }]
-  }
-]
+  }]}
 
 Rename src/Cross.res 21:28 xPrime
-[
-{
+{"documentChanges": [{
   "textDocument": {
   "version": null,
   "uri": "RenameWithInterface.resi"
@@ -55,8 +50,7 @@ Rename src/Cross.res 21:28 xPrime
   "range": {"start": {"line": 0, "character": 4}, "end": {"line": 0, "character": 5}},
   "newText": "xPrime"
   }]
-  },
-{
+  }, {
   "textDocument": {
   "version": null,
   "uri": "RenameWithInterface.res"
@@ -65,8 +59,7 @@ Rename src/Cross.res 21:28 xPrime
   "range": {"start": {"line": 0, "character": 4}, "end": {"line": 0, "character": 5}},
   "newText": "xPrime"
   }]
-  },
-{
+  }, {
   "textDocument": {
   "version": null,
   "uri": "Cross.res"
@@ -78,8 +71,7 @@ Rename src/Cross.res 21:28 xPrime
   "range": {"start": {"line": 21, "character": 28}, "end": {"line": 21, "character": 29}},
   "newText": "xPrime"
   }]
-  }
-]
+  }]}
 
 TypeDefinition src/Cross.res 24:5
 {"uri": "TypeDefinition.res", "range": {"start": {"line": 2, "character": 0}, "end": {"line": 2, "character": 28}}}
diff --git a/analysis/tests/src/expected/Rename.res.txt b/analysis/tests/src/expected/Rename.res.txt
index 5cd2adfee..6b6d6cc68 100644
--- a/analysis/tests/src/expected/Rename.res.txt
+++ b/analysis/tests/src/expected/Rename.res.txt
@@ -1,6 +1,5 @@
 Rename src/Rename.res 0:4 y
-[
-{
+{"documentChanges": [{
   "textDocument": {
   "version": null,
   "uri": "Rename.res"
@@ -15,12 +14,10 @@ Rename src/Rename.res 0:4 y
   "range": {"start": {"line": 7, "character": 8}, "end": {"line": 7, "character": 9}},
   "newText": "y"
   }]
-  }
-]
+  }]}
 
 Rename src/Rename.res 9:19 yy
-[
-{
+{"documentChanges": [{
   "textDocument": {
   "version": null,
   "uri": "Rename.res"
@@ -32,6 +29,5 @@ Rename src/Rename.res 9:19 yy
   "range": {"start": {"line": 9, "character": 19}, "end": {"line": 9, "character": 21}},
   "newText": "yy"
   }]
-  }
-]
+  }]}
 
diff --git a/analysis/tests/src/expected/RenameWithInterface.res.txt b/analysis/tests/src/expected/RenameWithInterface.res.txt
index a13988fa9..10c866089 100644
--- a/analysis/tests/src/expected/RenameWithInterface.res.txt
+++ b/analysis/tests/src/expected/RenameWithInterface.res.txt
@@ -1,6 +1,5 @@
 Rename src/RenameWithInterface.res 0:4 y
-[
-{
+{"documentChanges": [{
   "textDocument": {
   "version": null,
   "uri": "RenameWithInterface.resi"
@@ -9,8 +8,7 @@ Rename src/RenameWithInterface.res 0:4 y
   "range": {"start": {"line": 0, "character": 4}, "end": {"line": 0, "character": 5}},
   "newText": "y"
   }]
-  },
-{
+  }, {
   "textDocument": {
   "version": null,
   "uri": "RenameWithInterface.res"
@@ -19,8 +17,7 @@ Rename src/RenameWithInterface.res 0:4 y
   "range": {"start": {"line": 0, "character": 4}, "end": {"line": 0, "character": 5}},
   "newText": "y"
   }]
-  },
-{
+  }, {
   "textDocument": {
   "version": null,
   "uri": "Cross.res"
@@ -32,6 +29,5 @@ Rename src/RenameWithInterface.res 0:4 y
   "range": {"start": {"line": 21, "character": 28}, "end": {"line": 21, "character": 29}},
   "newText": "y"
   }]
-  }
-]
+  }]}
 
diff --git a/analysis/tests/src/expected/RenameWithInterface.resi.txt b/analysis/tests/src/expected/RenameWithInterface.resi.txt
index 2a1dabb44..4a9c40d36 100644
--- a/analysis/tests/src/expected/RenameWithInterface.resi.txt
+++ b/analysis/tests/src/expected/RenameWithInterface.resi.txt
@@ -1,6 +1,5 @@
 Rename src/RenameWithInterface.resi 0:4 y
-[
-{
+{"documentChanges": [{
   "textDocument": {
   "version": null,
   "uri": "RenameWithInterface.resi"
@@ -9,8 +8,7 @@ Rename src/RenameWithInterface.resi 0:4 y
   "range": {"start": {"line": 0, "character": 4}, "end": {"line": 0, "character": 5}},
   "newText": "y"
   }]
-  },
-{
+  }, {
   "textDocument": {
   "version": null,
   "uri": "RenameWithInterface.res"
@@ -19,8 +17,7 @@ Rename src/RenameWithInterface.resi 0:4 y
   "range": {"start": {"line": 0, "character": 4}, "end": {"line": 0, "character": 5}},
   "newText": "y"
   }]
-  },
-{
+  }, {
   "textDocument": {
   "version": null,
   "uri": "Cross.res"
@@ -32,6 +29,5 @@ Rename src/RenameWithInterface.resi 0:4 y
   "range": {"start": {"line": 21, "character": 28}, "end": {"line": 21, "character": 29}},
   "newText": "y"
   }]
-  }
-]
+  }]}
 
diff --git a/analysis/tests/src/expected/Xform.res.txt b/analysis/tests/src/expected/Xform.res.txt
index d298604ae..504ca9bcf 100644
--- a/analysis/tests/src/expected/Xform.res.txt
+++ b/analysis/tests/src/expected/Xform.res.txt
@@ -99,3 +99,72 @@ newText:
       }
     }
 
+Xform src/Xform.res 68:2
+Hit: Move type definition into its own module
+{"start": {"line": 68, "character": 0}, "end": {"line": 68, "character": 36}}
+newText:
+<--here
+module ReadState = {
+  type t = New | Unread | Read
+}
+{"start": {"line": 71, "character": 16}, "end": {"line": 71, "character": 25}}
+newText:
+                <--here
+                ReadState.t
+
+Xform src/Xform.res 76:2
+Hit: Move type definition into its own module
+{"start": {"line": 73, "character": 0}, "end": {"line": 76, "character": 25}}
+newText:
+<--here
+module Account = {
+  type t =
+    | None
+    | Instagram(string)
+    | Facebook(string, int)
+}
+
+Xform src/Xform.res 82:2
+
+Xform src/Xform.res 88:2
+Hit: Move type definition into its own module
+{"start": {"line": 85, "character": 0}, "end": {"line": 88, "character": 25}}
+newText:
+<--here
+module User = {
+  type t = {
+    name: string,
+    age: int,
+  }
+  and response = Yes | No
+}
+{"start": {"line": 98, "character": 21}, "end": {"line": 98, "character": 25}}
+newText:
+                     <--here
+                     User.name
+{"start": {"line": 98, "character": 45}, "end": {"line": 98, "character": 49}}
+newText:
+                                             <--here
+                                             User.name
+{"start": {"line": 100, "character": 20}, "end": {"line": 100, "character": 23}}
+newText:
+                    <--here
+                    User.Yes
+
+Xform src/Xform.res 91:2
+Hit: Move type definition into its own module
+{"start": {"line": 91, "character": 0}, "end": {"line": 91, "character": 25}}
+newText:
+<--here
+module MyType = {
+  type t = This | That
+}
+{"start": {"line": 94, "character": 15}, "end": {"line": 94, "character": 21}}
+newText:
+               <--here
+               MyType.t
+{"start": {"line": 96, "character": 20}, "end": {"line": 96, "character": 24}}
+newText:
+                    <--here
+                    MyType.This
+
diff --git a/server/src/server.ts b/server/src/server.ts
index 130aa604e..a5d33c034 100644
--- a/server/src/server.ts
+++ b/server/src/server.ts
@@ -531,7 +531,7 @@ function rename(msg: p.RequestMessage) {
   // https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_rename
   let params = msg.params as p.RenameParams;
   let filePath = fileURLToPath(params.textDocument.uri);
-  let documentChanges: (p.RenameFile | p.TextDocumentEdit)[] | null =
+  let result: WorkspaceEdit | null =
     utils.runAnalysisAfterSanityCheck(filePath, [
       "rename",
       filePath,
@@ -539,10 +539,6 @@ function rename(msg: p.RequestMessage) {
       params.position.character,
       params.newName,
     ]);
-  let result: WorkspaceEdit | null = null;
-  if (documentChanges !== null) {
-    result = { documentChanges };
-  }
   let response: p.ResponseMessage = {
     jsonrpc: c.jsonrpcVersion,
     id: msg.id,