diff --git a/ts/flexbuffers/reference-util.ts b/ts/flexbuffers/reference-util.ts
new file mode 100644
index 0000000..a5eb48d
--- /dev/null
+++ b/ts/flexbuffers/reference-util.ts
@@ -0,0 +1,119 @@
+import { BitWidth } from './bit-width'
+import { toByteWidth, fromByteWidth } from './bit-width-util'
+import { toUTF8Array, fromUTF8Array } from './flexbuffers-util'
+import { Reference } from './reference'
+
+import { Long } from '../long'
+
+export function validateOffset(dataView: DataView, offset: number, width: number): void {
+  if (dataView.byteLength <= offset + width || (offset & (toByteWidth(width) - 1)) !== 0) {
+    throw "Bad offset: " + offset + ", width: " + width;
+  }
+}
+
+export function readInt(dataView: DataView, offset: number, width: number): number | Long | bigint {
+  if (width < 2) {
+    if (width < 1) {
+      return dataView.getInt8(offset);
+    } else {
+      return dataView.getInt16(offset, true);
+    }
+  } else {
+    if (width < 3) {
+      return dataView.getInt32(offset, true)
+    } else {
+      if (dataView.setBigInt64 === undefined) {
+        return new Long(dataView.getUint32(offset, true), dataView.getUint32(offset + 4, true))
+      }
+      return dataView.getBigInt64(offset, true)
+    }
+  }
+}
+
+export function readUInt(dataView: DataView, offset: number, width: number): number | Long | bigint {
+  if (width < 2) {
+    if (width < 1) {
+      return dataView.getUint8(offset);
+    } else {
+      return dataView.getUint16(offset, true);
+    }
+  } else {
+    if (width < 3) {
+      return dataView.getUint32(offset, true)
+    } else {
+      if (dataView.getBigUint64 === undefined) {
+        return new Long(dataView.getUint32(offset, true), dataView.getUint32(offset + 4, true))
+      }
+      return dataView.getBigUint64(offset, true)
+    }
+  }
+}
+
+export function readFloat(dataView: DataView, offset: number, width: number): number {
+  if (width < BitWidth.WIDTH32) {
+    throw "Bad width: " + width;
+  }
+  if (width === BitWidth.WIDTH32) {
+    return dataView.getFloat32(offset, true);
+  }
+  return dataView.getFloat64(offset, true);
+}
+
+export function indirect(dataView: DataView, offset: number, width: number): number {
+  const step = readUInt(dataView, offset, width) as number;
+  return offset - step;
+}
+
+export function keyIndex(key: string, dataView: DataView, offset: number, parentWidth: number, byteWidth: number, length: number): number | null {
+  const input = toUTF8Array(key);
+  const keysVectorOffset = indirect(dataView, offset, parentWidth) - byteWidth * 3;
+  const bitWidth = fromByteWidth(byteWidth);
+  const indirectOffset = keysVectorOffset - (readUInt(dataView, keysVectorOffset, bitWidth) as number);
+  const _byteWidth = readUInt(dataView, keysVectorOffset + byteWidth, bitWidth) as number;
+  let low = 0;
+  let high = length - 1;
+  while (low <= high) {
+    const mid = (high + low) >> 1;
+    const dif = diffKeys(input, mid, dataView, indirectOffset, _byteWidth);
+    if (dif === 0) return mid;
+    if (dif < 0) {
+      high = mid - 1;
+    } else {
+      low = mid + 1;
+    }
+  }
+  return null;
+}
+
+export function diffKeys(input: Uint8Array, index: number, dataView: DataView, offset: number, width: number): number {
+  const keyOffset = offset + index * width;
+  const keyIndirectOffset = keyOffset - (readUInt(dataView, keyOffset, fromByteWidth(width)) as number);
+  for (let i = 0; i < input.length; i++) {
+    const dif = input[i] - dataView.getUint8(keyIndirectOffset + i);
+    if (dif !== 0) {
+      return dif;
+    }
+  }
+  return dataView.getUint8(keyIndirectOffset + input.length) === 0 ? 0 : -1;
+}
+
+export function valueForIndexWithKey(index: number, key: string, dataView: DataView, offset: number, parentWidth: number, byteWidth: number, length: number, path: string): Reference {
+  const _indirect = indirect(dataView, offset, parentWidth);
+  const elementOffset = _indirect + index * byteWidth;
+  const packedType = dataView.getUint8(_indirect + length * byteWidth + index);
+  return new Reference(dataView, elementOffset, fromByteWidth(byteWidth), packedType, `${path}/${key}`)
+}
+
+export function keyForIndex(index: number, dataView: DataView, offset: number, parentWidth: number, byteWidth: number): string {
+  const keysVectorOffset = indirect(dataView, offset, parentWidth) - byteWidth * 3;
+  const bitWidth = fromByteWidth(byteWidth);
+  const indirectOffset = keysVectorOffset - (readUInt(dataView, keysVectorOffset, bitWidth) as number);
+  const _byteWidth = readUInt(dataView, keysVectorOffset + byteWidth, bitWidth) as number;
+  const keyOffset = indirectOffset + index * _byteWidth;
+  const keyIndirectOffset = keyOffset - (readUInt(dataView, keyOffset, fromByteWidth(_byteWidth)) as number);
+  let length = 0;
+  while (dataView.getUint8(keyIndirectOffset + length) !== 0) {
+    length++;
+  }
+  return fromUTF8Array(new Uint8Array(dataView.buffer, keyIndirectOffset, length));
+}
\ No newline at end of file
