diff --git a/README.md b/README.md
index 60dcf892..d36b15b8 100644
--- a/README.md
+++ b/README.md
@@ -241,6 +241,8 @@ necessary.
   </p>
   <pre>const yarray = new Y.Array()</pre>
   <dl>
+    <b><code>parent:Y.AbstractType|null</code></b>
+    <dd></dd>
     <b><code>insert(index:number, content:Array&lt;object|boolean|Array|string|number|Uint8Array|Y.Type&gt;)</code></b>
     <dd>
 Insert content at <var>index</var>. Note that content is an array of elements.
@@ -312,6 +314,8 @@ or any of its children.
   </p>
   <pre><code>const ymap = new Y.Map()</code></pre>
   <dl>
+    <b><code>parent:Y.AbstractType|null</code></b>
+    <dd></dd>
     <b><code>get(key:string):object|boolean|string|number|Uint8Array|Y.Type</code></b>
     <dd></dd>
     <b><code>set(key:string, value:object|boolean|string|number|Uint8Array|Y.Type)</code></b>
@@ -391,6 +395,8 @@ YTextEvents compute changes as deltas.
   </p>
   <pre>const ytext = new Y.Text()</pre>
   <dl>
+    <b><code>parent:Y.AbstractType|null</code></b>
+    <dd></dd>
     <b><code>insert(index:number, content:string, [formattingAttributes:Object&lt;string,string&gt;])</code></b>
     <dd>
       Insert a string at <var>index</var> and assign formatting attributes to it.
@@ -449,6 +455,10 @@ or any of its children.
   </p>
   <pre><code>const yxml = new Y.XmlFragment()</code></pre>
   <dl>
+    <b><code>parent:Y.AbstractType|null</code></b>
+    <dd></dd>
+    <b><code>firstChild:Y.XmlElement|Y.XmlText|null</code></b>
+    <dd></dd>
     <b><code>insert(index:number, content:Array&lt;Y.XmlElement|Y.XmlText&gt;)</code></b>
     <dd></dd>
     <b><code>delete(index:number, length:number)</code></b>
@@ -504,6 +514,14 @@ content and be actually XML compliant.
   </p>
   <pre><code>const yxml = new Y.XmlElement()</code></pre>
   <dl>
+    <b><code>parent:Y.AbstractType|null</code></b>
+    <dd></dd>
+    <b><code>firstChild:Y.XmlElement|Y.XmlText|null</code></b>
+    <dd></dd>
+    <b><code>nextSibling:Y.XmlElement|Y.XmlText|null</code></b>
+    <dd></dd>
+    <b><code>prevSibling:Y.XmlElement|Y.XmlText|null</code></b>
+    <dd></dd>
     <b><code>insert(index:number, content:Array&lt;Y.XmlElement|Y.XmlText&gt;)</code></b>
     <dd></dd>
     <b><code>delete(index:number, length:number)</code></b>
diff --git a/src/types/AbstractType.js b/src/types/AbstractType.js
index c3513d68..3b6aa581 100644
--- a/src/types/AbstractType.js
+++ b/src/types/AbstractType.js
@@ -287,6 +287,13 @@ export class AbstractType {
     this._searchMarker = null
   }
 
+  /**
+   * @return {AbstractType<any>|null}
+   */
+  get parent () {
+    return this._item ? /** @type {AbstractType<any>} */ (this._item.parent) : null
+  }
+
   /**
    * Integrate this type into the Yjs instance.
    *
diff --git a/src/types/YXmlElement.js b/src/types/YXmlElement.js
index 0757e1b2..3b64fa51 100644
--- a/src/types/YXmlElement.js
+++ b/src/types/YXmlElement.js
@@ -8,7 +8,7 @@ import {
   typeMapGetAll,
   typeListForEach,
   YXmlElementRefID,
-  AbstractType, AbstractUpdateDecoder, AbstractUpdateEncoder, Snapshot, Doc, Item // eslint-disable-line
+  YXmlText, ContentType, AbstractType, AbstractUpdateDecoder, AbstractUpdateEncoder, Snapshot, Doc, Item // eslint-disable-line
 } from '../internals.js'
 
 /**
@@ -28,6 +28,22 @@ export class YXmlElement extends YXmlFragment {
     this._prelimAttrs = new Map()
   }
 
+  /**
+   * @type {YXmlElement|YXmlText|null}
+   */
+  get nextSibling () {
+    const n = this._item ? this._item.next : null
+    return n ? /** @type {YXmlElement|YXmlText} */ (/** @type {ContentType} */ (n.content).type) : null
+  }
+
+  /**
+   * @type {YXmlElement|YXmlText|null}
+   */
+  get prevSibling () {
+    const n = this._item ? this._item.prev : null
+    return n ? /** @type {YXmlElement|YXmlText} */ (/** @type {ContentType} */ (n.content).type) : null
+  }
+
   /**
    * Integrate this type into the Yjs instance.
    *
diff --git a/src/types/YXmlFragment.js b/src/types/YXmlFragment.js
index 711c9687..41c581e1 100644
--- a/src/types/YXmlFragment.js
+++ b/src/types/YXmlFragment.js
@@ -130,6 +130,14 @@ export class YXmlFragment extends AbstractType {
     this._prelimContent = []
   }
 
+  /**
+   * @type {YXmlElement|YXmlText|null}
+   */
+  get firstChild () {
+    const first = this._first
+    return first ? first.content.getContent()[0] : null
+  }
+
   /**
    * Integrate this type into the Yjs instance.
    *
diff --git a/src/types/YXmlText.js b/src/types/YXmlText.js
index 697e31c9..dd8d892d 100644
--- a/src/types/YXmlText.js
+++ b/src/types/YXmlText.js
@@ -2,7 +2,7 @@
 import {
   YText,
   YXmlTextRefID,
-  AbstractUpdateDecoder, AbstractUpdateEncoder // eslint-disable-line
+  ContentType, YXmlElement, AbstractUpdateDecoder, AbstractUpdateEncoder // eslint-disable-line
 } from '../internals.js'
 
 /**
@@ -10,6 +10,22 @@ import {
  * simple formatting information like bold and italic.
  */
 export class YXmlText extends YText {
+  /**
+   * @type {YXmlElement|YXmlText|null}
+   */
+  get nextSibling () {
+    const n = this._item ? this._item.next : null
+    return n ? /** @type {YXmlElement|YXmlText} */ (/** @type {ContentType} */ (n.content).type) : null
+  }
+
+  /**
+   * @type {YXmlElement|YXmlText|null}
+   */
+  get prevSibling () {
+    const n = this._item ? this._item.prev : null
+    return n ? /** @type {YXmlElement|YXmlText} */ (/** @type {ContentType} */ (n.content).type) : null
+  }
+
   _copy () {
     return new YXmlText()
   }
diff --git a/tests/y-xml.tests.js b/tests/y-xml.tests.js
index d59ee6c8..48132175 100644
--- a/tests/y-xml.tests.js
+++ b/tests/y-xml.tests.js
@@ -87,3 +87,19 @@ export const testYtextAttributes = tc => {
   t.compare(ytext.getAttribute('test'), 42)
   t.compare(ytext.getAttributes(), { test: 42 })
 }
+
+/**
+ * @param {t.TestCase} tc
+ */
+export const testSiblings = tc => {
+  const ydoc = new Y.Doc()
+  const yxml = ydoc.getXmlFragment()
+  const first = new Y.XmlText()
+  const second = new Y.XmlElement('p')
+  yxml.insert(0, [first, second])
+  t.assert(first.nextSibling === second)
+  t.assert(second.prevSibling === first)
+  t.assert(first.parent === yxml)
+  t.assert(yxml.parent === null)
+  t.assert(yxml.firstChild === first)
+}