diff --git a/src/main/java/io/vertx/core/json/JsonArray.java b/src/main/java/io/vertx/core/json/JsonArray.java
--- a/src/main/java/io/vertx/core/json/JsonArray.java
+++ b/src/main/java/io/vertx/core/json/JsonArray.java
@@ -20,12 +20,7 @@
 import io.vertx.core.shareddata.impl.ClusterSerializable;
 
 import java.time.Instant;
-import java.util.ArrayList;
-import java.util.Base64;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
+import java.util.*;
 import java.util.stream.Stream;
 
 import static java.time.format.DateTimeFormatter.ISO_INSTANT;
@@ -477,10 +472,17 @@ public boolean remove(Object value) {
    * Remove the value at the specified position in the JSON array.
    *
    * @param pos  the position to remove the value at
-   * @return the removed value if removed, null otherwise
+   * @return the removed value if removed, null otherwise. If the value is a Map, a {@link JsonObject} is built from
+   * this Map and returned. It the value is a List, a {@link JsonArray} is built form this List and returned.
    */
   public Object remove(int pos) {
-    return list.remove(pos);
+    Object removed = list.remove(pos);
+    if (removed instanceof Map) {
+      return new JsonObject((Map) removed);
+    } else if (removed instanceof ArrayList) {
+      return new JsonArray((List) removed);
+    }
+    return removed;
   }
 
   /**

diff --git a/src/test/java/io/vertx/test/core/JsonArrayTest.java b/src/test/java/io/vertx/test/core/JsonArrayTest.java
--- a/src/test/java/io/vertx/test/core/JsonArrayTest.java
+++ b/src/test/java/io/vertx/test/core/JsonArrayTest.java
@@ -1063,6 +1063,25 @@ public void testStreamCorrectTypes() throws Exception {
     testStreamCorrectTypes(object);
   }
 
+  @Test
+  public void testRemoveMethodReturnedObject() {
+    JsonArray obj = new JsonArray();
+    obj.add("bar")
+        .add(new JsonObject().put("name", "vert.x").put("count", 2))
+        .add(new JsonArray().add(1.0).add(2.0));
+
+    Object removed = obj.remove(0);
+    assertTrue(removed instanceof String);
+
+    removed = obj.remove(0);
+    assertTrue(removed instanceof JsonObject);
+    assertEquals(((JsonObject) removed).getString("name"), "vert.x");
+
+    removed = obj.remove(0);
+    assertTrue(removed instanceof JsonArray);
+    assertEquals(((JsonArray) removed).getDouble(0), 1.0, 0.0);
+  }
+
   private void testStreamCorrectTypes(JsonObject object) {
     object.getJsonArray("object1").stream().forEach(innerMap -> {
       assertTrue("Expecting JsonObject, found: " + innerMap.getClass().getCanonicalName(), innerMap instanceof JsonObject);
diff --git a/src/test/java/io/vertx/test/core/JsonObjectTest.java b/src/test/java/io/vertx/test/core/JsonObjectTest.java
--- a/src/test/java/io/vertx/test/core/JsonObjectTest.java
+++ b/src/test/java/io/vertx/test/core/JsonObjectTest.java
@@ -1629,6 +1629,28 @@ public void testStreamCorrectTypes() throws Exception {
     testStreamCorrectTypes(object);
   }
 
+  @Test
+  public void testRemoveMethodReturnedObject() {
+    JsonObject obj = new JsonObject();
+    obj.put("simple", "bar")
+        .put("object", new JsonObject().put("name", "vert.x").put("count", 2))
+        .put("array", new JsonArray().add(1.0).add(2.0));
+
+    Object removed = obj.remove("missing");
+    assertNull(removed);
+
+    removed = obj.remove("simple");
+    assertTrue(removed instanceof String);
+
+    removed = obj.remove("object");
+    assertTrue(removed instanceof JsonObject);
+    assertEquals(((JsonObject) removed).getString("name"), "vert.x");
+
+    removed = obj.remove("array");
+    assertTrue(removed instanceof JsonArray);
+    assertEquals(((JsonArray) removed).getDouble(0), 1.0, 0.0);
+  }
+
   private void testStreamCorrectTypes(JsonObject object) {
     object.stream().forEach(entry -> {
       String key = entry.getKey();

JsonArray.remove(int pos) should return JsonArray or JsonObject instead of their underlying implementations
The current implementation returns / leaks a `java.util.ArrayList<?>` in case of a `JsonArray` or a Map in case of a `JsonObject`. It should check for these implementations and return a JsonArray or JsonObject wrapper.

See https://github.com/eclipse/vert.x/blob/master/src/main/java/io/vertx/core/json/JsonArray.java#L482

