diff --git a/ts/builder.ts b/ts/builder.ts
new file mode 100644
index 0000000..6be72fb
--- /dev/null
+++ b/ts/builder.ts
@@ -0,0 +1,628 @@
+import { ByteBuffer } from "./byte-buffer"
+import { SIZEOF_SHORT, SIZE_PREFIX_LENGTH, SIZEOF_INT, FILE_IDENTIFIER_LENGTH } from "./constants"
+import { Offset, IGeneratedObject } from "./types"
+import { Long } from "./long"
+
+export class Builder {
+    private bb: ByteBuffer
+    /** Remaining space in the ByteBuffer. */
+    private space: number
+    /** Minimum alignment encountered so far. */
+    private minalign = 1
+    /** The vtable for the current table. */
+    private vtable: number[] | null = null
+    /** The amount of fields we're actually using. */
+    private vtable_in_use = 0
+    /** Whether we are currently serializing a table. */
+    private isNested = false;
+    /** Starting offset of the current struct/table. */
+    private object_start = 0
+    /** List of offsets of all vtables. */
+    private vtables: number[] = []
+    /** For the current vector being built. */
+    private vector_num_elems = 0 
+    /** False omits default values from the serialized data */
+    private force_defaults = false;
+    
+    private string_maps: Map<string | Uint8Array, number> | null = null;
+  
+    /**
+     * Create a FlatBufferBuilder.
+     */
+    constructor(opt_initial_size?: number) {
+      let initial_size: number;
+  
+      if (!opt_initial_size) {
+        initial_size = 1024;
+      } else {
+        initial_size = opt_initial_size;
+      }
+  
+      /**
+       * @type {ByteBuffer}
+       * @private
+       */
+      this.bb = ByteBuffer.allocate(initial_size);
+      this.space = initial_size;
+    }
+  
+  
+    clear(): void {
+      this.bb.clear();
+      this.space = this.bb.capacity();
+      this.minalign = 1;
+      this.vtable = null;
+      this.vtable_in_use = 0;
+      this.isNested = false;
+      this.object_start = 0;
+      this.vtables = [];
+      this.vector_num_elems = 0;
+      this.force_defaults = false;
+      this.string_maps = null;
+    }
+  
+    /**
+     * In order to save space, fields that are set to their default value
+     * don't get serialized into the buffer. Forcing defaults provides a
+     * way to manually disable this optimization.
+     *
+     * @param forceDefaults true always serializes default values
+     */
+    forceDefaults(forceDefaults: boolean): void {
+      this.force_defaults = forceDefaults;
+    }
+  
+    /**
+     * Get the ByteBuffer representing the FlatBuffer. Only call this after you've
+     * called finish(). The actual data starts at the ByteBuffer's current position,
+     * not necessarily at 0.
+     */
+    dataBuffer(): ByteBuffer {
+      return this.bb;
+    }
+  
+    /**
+     * Get the bytes representing the FlatBuffer. Only call this after you've
+     * called finish().
+     */
+    asUint8Array(): Uint8Array {
+      return this.bb.bytes().subarray(this.bb.position(), this.bb.position() + this.offset());
+    }
+  
+    /**
+     * Prepare to write an element of `size` after `additional_bytes` have been
+     * written, e.g. if you write a string, you need to align such the int length
+     * field is aligned to 4 bytes, and the string data follows it directly. If all
+     * you need to do is alignment, `additional_bytes` will be 0.
+     *
+     * @param size This is the of the new element to write
+     * @param additional_bytes The padding size
+     */
+    prep(size: number, additional_bytes: number): void {
+      // Track the biggest thing we've ever aligned to.
+      if (size > this.minalign) {
+        this.minalign = size;
+      }
+  
+      // Find the amount of alignment needed such that `size` is properly
+      // aligned after `additional_bytes`
+      const align_size = ((~(this.bb.capacity() - this.space + additional_bytes)) + 1) & (size - 1);
+  
+      // Reallocate the buffer if needed.
+      while (this.space < align_size + size + additional_bytes) {
+        const old_buf_size = this.bb.capacity();
+        this.bb = Builder.growByteBuffer(this.bb);
+        this.space += this.bb.capacity() - old_buf_size;
+      }
+  
+      this.pad(align_size);
+    }
+  
+    pad(byte_size: number): void {
+      for (let i = 0; i < byte_size; i++) {
+        this.bb.writeInt8(--this.space, 0);
+      }
+    }
+  
+    writeInt8(value: number): void {
+      this.bb.writeInt8(this.space -= 1, value);
+    }
+  
+    writeInt16(value: number): void {
+      this.bb.writeInt16(this.space -= 2, value);
+    }
+  
+    writeInt32(value: number): void {
+      this.bb.writeInt32(this.space -= 4, value);
+    }
+  
+    writeInt64(value: Long): void {
+      this.bb.writeInt64(this.space -= 8, value);
+    }
+  
+    writeFloat32(value: number): void {
+      this.bb.writeFloat32(this.space -= 4, value);
+    }
+  
+    writeFloat64(value: number): void {
+      this.bb.writeFloat64(this.space -= 8, value);
+    }
+  
+    /**
+     * Add an `int8` to the buffer, properly aligned, and grows the buffer (if necessary).
+     * @param value The `int8` to add the the buffer.
+     */
+    addInt8(value: number): void {
+      this.prep(1, 0);
+      this.writeInt8(value);
+    }
+  
+    /**
+     * Add an `int16` to the buffer, properly aligned, and grows the buffer (if necessary).
+     * @param value The `int16` to add the the buffer.
+     */
+    addInt16(value: number): void {
+      this.prep(2, 0);
+      this.writeInt16(value);
+    }
+  
+    /**
+     * Add an `int32` to the buffer, properly aligned, and grows the buffer (if necessary).
+     * @param value The `int32` to add the the buffer.
+     */
+    addInt32(value: number): void {
+      this.prep(4, 0);
+      this.writeInt32(value);
+    }
+  
+    /**
+     * Add an `int64` to the buffer, properly aligned, and grows the buffer (if necessary).
+     * @param value The `int64` to add the the buffer.
+     */
+    addInt64(value: Long): void {
+      this.prep(8, 0);
+      this.writeInt64(value);
+    }
+  
+    /**
+     * Add a `float32` to the buffer, properly aligned, and grows the buffer (if necessary).
+     * @param value The `float32` to add the the buffer.
+     */
+    addFloat32(value: number): void {
+      this.prep(4, 0);
+      this.writeFloat32(value);
+    }
+  
+    /**
+     * Add a `float64` to the buffer, properly aligned, and grows the buffer (if necessary).
+     * @param value The `float64` to add the the buffer.
+     */
+    addFloat64(value: number): void {
+      this.prep(8, 0);
+      this.writeFloat64(value);
+    }
+  
+    addFieldInt8(voffset: number, value: number, defaultValue: number): void {
+      if (this.force_defaults || value != defaultValue) {
+        this.addInt8(value);
+        this.slot(voffset);
+      }
+    }
+  
+    addFieldInt16(voffset: number, value: number, defaultValue: number): void {
+      if (this.force_defaults || value != defaultValue) {
+        this.addInt16(value);
+        this.slot(voffset);
+      }
+    }
+  
+    addFieldInt32(voffset: number, value: number, defaultValue: number): void {
+      if (this.force_defaults || value != defaultValue) {
+        this.addInt32(value);
+        this.slot(voffset);
+      }
+    }
+  
+    addFieldInt64(voffset: number, value: Long, defaultValue: Long): void {
+      if (this.force_defaults || !value.equals(defaultValue)) {
+        this.addInt64(value);
+        this.slot(voffset);
+      }
+    }
+  
+    addFieldFloat32(voffset: number, value: number, defaultValue: number): void {
+      if (this.force_defaults || value != defaultValue) {
+        this.addFloat32(value);
+        this.slot(voffset);
+      }
+    }
+  
+    addFieldFloat64(voffset: number, value: number, defaultValue: number): void {
+      if (this.force_defaults || value != defaultValue) {
+        this.addFloat64(value);
+        this.slot(voffset);
+      }
+    }
+  
+    addFieldOffset(voffset: number, value: Offset, defaultValue: Offset): void {
+      if (this.force_defaults || value != defaultValue) {
+        this.addOffset(value);
+        this.slot(voffset);
+      }
+    }
+  
+    /**
+     * Structs are stored inline, so nothing additional is being added. `d` is always 0.
+     */
+    addFieldStruct(voffset: number, value: Offset, defaultValue: Offset): void {
+      if (value != defaultValue) {
+        this.nested(value);
+        this.slot(voffset);
+      }
+    }
+  
+    /**
+     * Structures are always stored inline, they need to be created right
+     * where they're used.  You'll get this assertion failure if you
+     * created it elsewhere.
+     */
+    nested(obj: Offset): void {
+      if (obj != this.offset()) {
+        throw new Error('FlatBuffers: struct must be serialized inline.');
+      }
+    }
+  
+    /**
+     * Should not be creating any other object, string or vector
+     * while an object is being constructed
+     */
+    notNested(): void {
+      if (this.isNested) {
+        throw new Error('FlatBuffers: object serialization must not be nested.');
+      }
+    }
+  
+    /**
+     * Set the current vtable at `voffset` to the current location in the buffer.
+     */
+    slot(voffset: number): void {
+      if (this.vtable !== null)
+        this.vtable[voffset] = this.offset();
+    }
+  
+    /**
+     * @returns Offset relative to the end of the buffer.
+     */
+    offset(): Offset {
+      return this.bb.capacity() - this.space;
+    }
+  
+    /**
+     * Doubles the size of the backing ByteBuffer and copies the old data towards
+     * the end of the new buffer (since we build the buffer backwards).
+     *
+     * @param bb The current buffer with the existing data
+     * @returns A new byte buffer with the old data copied
+     * to it. The data is located at the end of the buffer.
+     *
+     * uint8Array.set() formally takes {Array<number>|ArrayBufferView}, so to pass
+     * it a uint8Array we need to suppress the type check:
+     * @suppress {checkTypes}
+     */
+    static growByteBuffer(bb: ByteBuffer): ByteBuffer {
+      const old_buf_size = bb.capacity();
+  
+      // Ensure we don't grow beyond what fits in an int.
+      if (old_buf_size & 0xC0000000) {
+        throw new Error('FlatBuffers: cannot grow buffer beyond 2 gigabytes.');
+      }
+  
+      const new_buf_size = old_buf_size << 1;
+      const nbb = ByteBuffer.allocate(new_buf_size);
+      nbb.setPosition(new_buf_size - old_buf_size);
+      nbb.bytes().set(bb.bytes(), new_buf_size - old_buf_size);
+      return nbb;
+    }
+  
+    /**
+     * Adds on offset, relative to where it will be written.
+     *
+     * @param offset The offset to add.
+     */
+    addOffset(offset: Offset): void {
+      this.prep(SIZEOF_INT, 0); // Ensure alignment is already done.
+      this.writeInt32(this.offset() - offset + SIZEOF_INT);
+    }
+  
+    /**
+     * Start encoding a new object in the buffer.  Users will not usually need to
+     * call this directly. The FlatBuffers compiler will generate helper methods
+     * that call this method internally.
+     */
+    startObject(numfields: number): void {
+      this.notNested();
+      if (this.vtable == null) {
+        this.vtable = [];
+      }
+      this.vtable_in_use = numfields;
+      for (let i = 0; i < numfields; i++) {
+        this.vtable[i] = 0; // This will push additional elements as needed
+      }
+      this.isNested = true;
+      this.object_start = this.offset();
+    }
+  
+    /**
+     * Finish off writing the object that is under construction.
+     *
+     * @returns The offset to the object inside `dataBuffer`
+     */
+    endObject(): Offset {
+      if (this.vtable == null || !this.isNested) {
+        throw new Error('FlatBuffers: endObject called without startObject');
+      }
+  
+      this.addInt32(0);
+      const vtableloc = this.offset();
+  
+      // Trim trailing zeroes.
+      let i = this.vtable_in_use - 1;
+      // eslint-disable-next-line no-empty
+      for (; i >= 0 && this.vtable[i] == 0; i--) {}
+      const trimmed_size = i + 1;
+  
+      // Write out the current vtable.
+      for (; i >= 0; i--) {
+        // Offset relative to the start of the table.
+        this.addInt16(this.vtable[i] != 0 ? vtableloc - this.vtable[i] : 0);
+      }
+  
+      const standard_fields = 2; // The fields below:
+      this.addInt16(vtableloc - this.object_start);
+      const len = (trimmed_size + standard_fields) * SIZEOF_SHORT;
+      this.addInt16(len);
+  
+      // Search for an existing vtable that matches the current one.
+      let existing_vtable = 0;
+      const vt1 = this.space;
+    outer_loop:
+      for (i = 0; i < this.vtables.length; i++) {
+        const vt2 = this.bb.capacity() - this.vtables[i];
+        if (len == this.bb.readInt16(vt2)) {
+          for (let j = SIZEOF_SHORT; j < len; j += SIZEOF_SHORT) {
+            if (this.bb.readInt16(vt1 + j) != this.bb.readInt16(vt2 + j)) {
+              continue outer_loop;
+            }
+          }
+          existing_vtable = this.vtables[i];
+          break;
+        }
+      }
+  
+      if (existing_vtable) {
+        // Found a match:
+        // Remove the current vtable.
+        this.space = this.bb.capacity() - vtableloc;
+  
+        // Point table to existing vtable.
+        this.bb.writeInt32(this.space, existing_vtable - vtableloc);
+      } else {
+        // No match:
+        // Add the location of the current vtable to the list of vtables.
+        this.vtables.push(this.offset());
+  
+        // Point table to current vtable.
+        this.bb.writeInt32(this.bb.capacity() - vtableloc, this.offset() - vtableloc);
+      }
+  
+      this.isNested = false;
+      return vtableloc as Offset;
+    }
+  
+    /**
+     * Finalize a buffer, poiting to the given `root_table`.
+     */
+    finish(root_table: Offset, opt_file_identifier?: string, opt_size_prefix?: boolean): void {
+      const size_prefix = opt_size_prefix ? SIZE_PREFIX_LENGTH : 0;
+      if (opt_file_identifier) {
+        const file_identifier = opt_file_identifier;
+        this.prep(this.minalign, SIZEOF_INT +
+          FILE_IDENTIFIER_LENGTH + size_prefix);
+        if (file_identifier.length != FILE_IDENTIFIER_LENGTH) {
+          throw new Error('FlatBuffers: file identifier must be length ' +
+            FILE_IDENTIFIER_LENGTH);
+        }
+        for (let i = FILE_IDENTIFIER_LENGTH - 1; i >= 0; i--) {
+          this.writeInt8(file_identifier.charCodeAt(i));
+        }
+      }
+      this.prep(this.minalign, SIZEOF_INT + size_prefix);
+      this.addOffset(root_table);
+      if (size_prefix) {
+        this.addInt32(this.bb.capacity() - this.space);
+      }
+      this.bb.setPosition(this.space);
+    }
+  
+    /**
+     * Finalize a size prefixed buffer, pointing to the given `root_table`.
+     */
+    finishSizePrefixed(this: Builder, root_table: Offset, opt_file_identifier?: string): void {
+      this.finish(root_table, opt_file_identifier, true);
+    }
+  
+    /**
+     * This checks a required field has been set in a given table that has
+     * just been constructed.
+     */
+    requiredField(table: Offset, field: number): void {
+      const table_start = this.bb.capacity() - table;
+      const vtable_start = table_start - this.bb.readInt32(table_start);
+      const ok = this.bb.readInt16(vtable_start + field) != 0;
+  
+      // If this fails, the caller will show what field needs to be set.
+      if (!ok) {
+        throw new Error('FlatBuffers: field ' + field + ' must be set');
+      }
+    }
+  
+    /**
+     * Start a new array/vector of objects.  Users usually will not call
+     * this directly. The FlatBuffers compiler will create a start/end
+     * method for vector types in generated code.
+     *
+     * @param elem_size The size of each element in the array
+     * @param num_elems The number of elements in the array
+     * @param alignment The alignment of the array
+     */
+    startVector(elem_size: number, num_elems: number, alignment: number): void {
+      this.notNested();
+      this.vector_num_elems = num_elems;
+      this.prep(SIZEOF_INT, elem_size * num_elems);
+      this.prep(alignment, elem_size * num_elems); // Just in case alignment > int.
+    }
+  
+    /**
+     * Finish off the creation of an array and all its elements. The array must be
+     * created with `startVector`.
+     *
+     * @returns The offset at which the newly created array
+     * starts.
+     */
+    endVector(): Offset {
+      this.writeInt32(this.vector_num_elems);
+      return this.offset();
+    }
+  
+    /**
+     * Encode the string `s` in the buffer using UTF-8. If the string passed has 
+     * already been seen, we return the offset of the already written string
+     *
+     * @param s The string to encode
+     * @return The offset in the buffer where the encoded string starts
+     */
+    createSharedString(s: string | Uint8Array): Offset {
+      if (!s) { return 0 }
+  
+      if (!this.string_maps) {
+        this.string_maps = new Map();
+      }
+  
+      if (this.string_maps.has(s)) {
+        return this.string_maps.get(s) as Offset
+      }
+      const offset = this.createString(s)
+      this.string_maps.set(s, offset)
+      return offset
+    }
+  
+    /**
+     * Encode the string `s` in the buffer using UTF-8. If a Uint8Array is passed
+     * instead of a string, it is assumed to contain valid UTF-8 encoded data.
+     *
+     * @param s The string to encode
+     * @return The offset in the buffer where the encoded string starts
+     */
+    createString(s: string | Uint8Array): Offset {
+      if (!s) { return 0 }
+      let utf8: string | Uint8Array | number[];
+      if (s instanceof Uint8Array) {
+        utf8 = s;
+      } else {
+        utf8 = [];
+        let i = 0;
+  
+        while (i < s.length) {
+          let codePoint;
+  
+          // Decode UTF-16
+          const a = s.charCodeAt(i++);
+          if (a < 0xD800 || a >= 0xDC00) {
+            codePoint = a;
+          } else {
+            const b = s.charCodeAt(i++);
+            codePoint = (a << 10) + b + (0x10000 - (0xD800 << 10) - 0xDC00);
+          }
+  
+          // Encode UTF-8
+          if (codePoint < 0x80) {
+            utf8.push(codePoint);
+          } else {
+            if (codePoint < 0x800) {
+              utf8.push(((codePoint >> 6) & 0x1F) | 0xC0);
+            } else {
+              if (codePoint < 0x10000) {
+                utf8.push(((codePoint >> 12) & 0x0F) | 0xE0);
+              } else {
+                utf8.push(
+                  ((codePoint >> 18) & 0x07) | 0xF0,
+                  ((codePoint >> 12) & 0x3F) | 0x80);
+              }
+              utf8.push(((codePoint >> 6) & 0x3F) | 0x80);
+            }
+            utf8.push((codePoint & 0x3F) | 0x80);
+          }
+        }
+      }
+  
+      this.addInt8(0);
+      this.startVector(1, utf8.length, 1);
+      this.bb.setPosition(this.space -= utf8.length);
+      for (let i = 0, offset = this.space, bytes = this.bb.bytes(); i < utf8.length; i++) {
+        bytes[offset++] = utf8[i];
+      }
+      return this.endVector();
+    }
+  
+    /**
+     * A helper function to avoid generated code depending on this file directly.
+     */
+    createLong(low: number, high: number): Long {
+      return Long.create(low, high);
+    }
+  
+    /**
+     * A helper function to pack an object
+     * 
+     * @returns offset of obj
+     */
+    createObjectOffset(obj: string | IGeneratedObject): Offset {
+      if(obj === null) {
+        return 0
+      }
+  
+      if(typeof obj === 'string') {
+        return this.createString(obj);
+      } else {
+        return obj.pack(this);
+      }
+    }
+  
+    /**
+     * A helper function to pack a list of object
+     * 
+     * @returns list of offsets of each non null object
+     */
+    createObjectOffsetList(list: string[]): Offset[] {
+      const ret = [];
+  
+      for(let i = 0; i < list.length; ++i) {
+        const val = list[i];
+  
+        if(val !== null) {
+          ret.push(this.createObjectOffset(val));
+        } else {
+          throw new Error(
+            'FlatBuffers: Argument for createObjectOffsetList cannot contain null.'); 
+        }
+      }
+      
+      return ret;
+    }
+  
+    createStructOffsetList(list: string[], startFunc: (builder: Builder, length: number) => void): Offset {
+      startFunc(this, list.length);
+      this.createObjectOffsetList(list);
+      return this.endVector();
+    }
+  }
\ No newline at end of file
diff --git a/ts/byte-buffer.ts b/ts/byte-buffer.ts
new file mode 100644
index 0000000..b936c7b
--- /dev/null
+++ b/ts/byte-buffer.ts
@@ -0,0 +1,351 @@
+import { FILE_IDENTIFIER_LENGTH, SIZEOF_INT } from "./constants";
+import { Long } from "./long";
+import { int32, isLittleEndian, float32, float64 } from "./utils";
+import { Offset, Table, IGeneratedObject } from "./types";
+import { Encoding } from "./encoding";
+
+export class ByteBuffer {
+    private position_ = 0;
+  
+    /**
+     * Create a new ByteBuffer with a given array of bytes (`Uint8Array`)
+     */
+    constructor(private bytes_: Uint8Array) { }
+  
+    /**
+     * Create and allocate a new ByteBuffer with a given size.
+     */
+    static allocate(byte_size: number): ByteBuffer {
+      return new ByteBuffer(new Uint8Array(byte_size));
+    }
+  
+    clear(): void {
+      this.position_ = 0;
+    }
+  
+    /**
+     * Get the underlying `Uint8Array`.
+     */
+    bytes(): Uint8Array {
+      return this.bytes_;
+    }
+  
+    /**
+     * Get the buffer's position.
+     */
+    position(): number {
+      return this.position_;
+    }
+  
+    /**
+     * Set the buffer's position.
+     */
+    setPosition(position: number): void {
+      this.position_ = position;
+    }
+  
+    /**
+     * Get the buffer's capacity.
+     */
+    capacity(): number {
+      return this.bytes_.length;
+    }
+  
+    readInt8(offset: number): number {
+      return this.readUint8(offset) << 24 >> 24;
+    }
+  
+    readUint8(offset: number): number {
+      return this.bytes_[offset];
+    }
+  
+    readInt16(offset: number): number {
+      return this.readUint16(offset) << 16 >> 16;
+    }
+  
+    readUint16(offset: number): number {
+      return this.bytes_[offset] | this.bytes_[offset + 1] << 8;
+    }
+  
+    readInt32(offset: number): number {
+      return this.bytes_[offset] | this.bytes_[offset + 1] << 8 | this.bytes_[offset + 2] << 16 | this.bytes_[offset + 3] << 24;
+    }
+  
+    readUint32(offset: number): number {
+      return this.readInt32(offset) >>> 0;
+    }
+  
+    readInt64(offset: number): Long {
+      return new Long(this.readInt32(offset), this.readInt32(offset + 4));
+    }
+  
+    readUint64(offset: number): Long {
+      return new Long(this.readUint32(offset), this.readUint32(offset + 4));
+    }
+  
+    readFloat32(offset: number): number {
+      int32[0] = this.readInt32(offset);
+      return float32[0];
+    }
+  
+    readFloat64(offset: number): number {
+      int32[isLittleEndian ? 0 : 1] = this.readInt32(offset);
+      int32[isLittleEndian ? 1 : 0] = this.readInt32(offset + 4);
+      return float64[0];
+    }
+  
+    writeInt8(offset: number, value: number): void {
+      this.bytes_[offset] = value;
+    }
+  
+    writeUint8(offset: number, value: number): void {
+      this.bytes_[offset] = value;
+    }
+  
+    writeInt16(offset: number, value: number): void {
+      this.bytes_[offset] = value;
+      this.bytes_[offset + 1] = value >> 8;
+    }
+  
+    writeUint16(offset: number, value: number): void {
+        this.bytes_[offset] = value;
+        this.bytes_[offset + 1] = value >> 8;
+    }
+  
+    writeInt32(offset: number, value: number): void {
+      this.bytes_[offset] = value;
+      this.bytes_[offset + 1] = value >> 8;
+      this.bytes_[offset + 2] = value >> 16;
+      this.bytes_[offset + 3] = value >> 24;
+    }
+  
+    writeUint32(offset: number, value: number): void {
+        this.bytes_[offset] = value;
+        this.bytes_[offset + 1] = value >> 8;
+        this.bytes_[offset + 2] = value >> 16;
+        this.bytes_[offset + 3] = value >> 24;
+    }
+  
+    writeInt64(offset: number, value: Long): void {
+      this.writeInt32(offset, value.low);
+      this.writeInt32(offset + 4, value.high);
+    }
+  
+    writeUint64(offset: number, value: Long): void {
+        this.writeUint32(offset, value.low);
+        this.writeUint32(offset + 4, value.high);
+    }
+  
+    writeFloat32(offset: number, value: number): void {
+      float32[0] = value;
+      this.writeInt32(offset, int32[0]);
+    }
+  
+    writeFloat64(offset: number, value: number): void {
+      float64[0] = value;
+      this.writeInt32(offset, int32[isLittleEndian ? 0 : 1]);
+      this.writeInt32(offset + 4, int32[isLittleEndian ? 1 : 0]);
+    }
+  
+    /**
+     * Return the file identifier.   Behavior is undefined for FlatBuffers whose
+     * schema does not include a file_identifier (likely points at padding or the
+     * start of a the root vtable).
+     */
+    getBufferIdentifier(): string {
+      if (this.bytes_.length < this.position_ + SIZEOF_INT +
+          FILE_IDENTIFIER_LENGTH) {
+        throw new Error(
+            'FlatBuffers: ByteBuffer is too short to contain an identifier.');
+      }
+      let result = "";
+      for (let i = 0; i < FILE_IDENTIFIER_LENGTH; i++) {
+        result += String.fromCharCode(
+            this.readInt8(this.position_ + SIZEOF_INT + i));
+      }
+      return result;
+    }
+  
+    /**
+     * Look up a field in the vtable, return an offset into the object, or 0 if the
+     * field is not present.
+     */
+    __offset(bb_pos: number, vtable_offset: number): Offset {
+      const vtable = bb_pos - this.readInt32(bb_pos);
+      return vtable_offset < this.readInt16(vtable) ? this.readInt16(vtable + vtable_offset) : 0;
+    }
+  
+    /**
+     * Initialize any Table-derived type to point to the union at the given offset.
+     */
+    __union(t: Table, offset: number): Table {
+      t.bb_pos = offset + this.readInt32(offset);
+      t.bb = this;
+      return t;
+    }
+  
+    /**
+     * Create a JavaScript string from UTF-8 data stored inside the FlatBuffer.
+     * This allocates a new string and converts to wide chars upon each access.
+     *
+     * To avoid the conversion to UTF-16, pass Encoding.UTF8_BYTES as
+     * the "optionalEncoding" argument. This is useful for avoiding conversion to
+     * and from UTF-16 when the data will just be packaged back up in another
+     * FlatBuffer later on.
+     *
+     * @param offset
+     * @param opt_encoding Defaults to UTF16_STRING
+     */
+    __string(offset: number, opt_encoding?: Encoding): string | Uint8Array {
+      offset += this.readInt32(offset);
+  
+      const length = this.readInt32(offset);
+      let result = '';
+      let i = 0;
+  
+      offset += SIZEOF_INT;
+  
+      if (opt_encoding === Encoding.UTF8_BYTES) {
+        return this.bytes_.subarray(offset, offset + length);
+      }
+  
+      while (i < length) {
+        let codePoint;
+  
+        // Decode UTF-8
+        const a = this.readUint8(offset + i++);
+        if (a < 0xC0) {
+          codePoint = a;
+        } else {
+          const b = this.readUint8(offset + i++);
+          if (a < 0xE0) {
+            codePoint =
+              ((a & 0x1F) << 6) |
+              (b & 0x3F);
+          } else {
+            const c = this.readUint8(offset + i++);
+            if (a < 0xF0) {
+              codePoint =
+                ((a & 0x0F) << 12) |
+                ((b & 0x3F) << 6) |
+                (c & 0x3F);
+            } else {
+              const d = this.readUint8(offset + i++);
+              codePoint =
+                ((a & 0x07) << 18) |
+                ((b & 0x3F) << 12) |
+                ((c & 0x3F) << 6) |
+                (d & 0x3F);
+            }
+          }
+        }
+  
+        // Encode UTF-16
+        if (codePoint < 0x10000) {
+          result += String.fromCharCode(codePoint);
+        } else {
+          codePoint -= 0x10000;
+          result += String.fromCharCode(
+            (codePoint >> 10) + 0xD800,
+            (codePoint & ((1 << 10) - 1)) + 0xDC00);
+        }
+      }
+  
+      return result;
+    }
+  
+    /**
+     * Handle unions that can contain string as its member, if a Table-derived type then initialize it, 
+     * if a string then return a new one
+     * 
+     * WARNING: strings are immutable in JS so we can't change the string that the user gave us, this 
+     * makes the behaviour of __union_with_string different compared to __union
+     */
+    __union_with_string(o: Table | string, offset: number) : Table | string {
+      if(typeof o === 'string') {
+        return this.__string(offset) as string;
+      } 
+      return this.__union(o, offset);
+    }
+  
+    /**
+     * Retrieve the relative offset stored at "offset"
+     */
+    __indirect(offset: Offset): Offset {
+      return offset + this.readInt32(offset);
+    }
+  
+    /**
+     * Get the start of data of a vector whose offset is stored at "offset" in this object.
+     */
+    __vector(offset: Offset): Offset {
+      return offset + this.readInt32(offset) + SIZEOF_INT; // data starts after the length
+    }
+  
+    /**
+     * Get the length of a vector whose offset is stored at "offset" in this object.
+     */
+    __vector_len(offset: Offset): Offset {
+      return this.readInt32(offset + this.readInt32(offset));
+    }
+  
+    __has_identifier(ident: string): boolean {
+      if (ident.length != FILE_IDENTIFIER_LENGTH) {
+        throw new Error('FlatBuffers: file identifier must be length ' +
+                        FILE_IDENTIFIER_LENGTH);
+      }
+      for (let i = 0; i < FILE_IDENTIFIER_LENGTH; i++) {
+        if (ident.charCodeAt(i) != this.readInt8(this.position() + SIZEOF_INT + i)) {
+          return false;
+        }
+      }
+      return true;
+    }
+  
+    /**
+     * A helper function to avoid generated code depending on this file directly.
+     */
+    createLong(low: number, high: number): Long {
+      return Long.create(low, high);
+    }
+  
+    /**
+     * A helper function for generating list for obj api
+     */
+    createScalarList(listAccessor: (i: number) => unknown, listLength: number) : unknown[] {
+      const ret: unknown[] = [];
+      for(let i = 0; i < listLength; ++i) {
+        if(listAccessor(i) !== null) {
+          ret.push(listAccessor(i));
+        }
+      }
+  
+      return ret;
+    }
+  
+    /**
+     * This function is here only to get around typescript type system
+     */
+    createStringList(listAccessor: (i: number) => unknown, listLength: number): unknown[] {
+      return this.createScalarList(listAccessor, listLength);
+    }
+  
+    /**
+     * A helper function for generating list for obj api
+     * @param listAccessor function that accepts an index and return data at that index
+     * @param listLength listLength
+     * @param res result list
+     */
+    createObjList(listAccessor: (i: number) => IGeneratedObject, listLength: number): IGeneratedObject[] {
+      const ret: IGeneratedObject[] = [];
+      for(let i = 0; i < listLength; ++i) {
+        const val = listAccessor(i);
+        if(val !== null) {
+          ret.push(val.unpack());
+        }
+      }
+      
+      return ret;
+    }
+  
+  }
\ No newline at end of file
diff --git a/ts/constants.ts b/ts/constants.ts
new file mode 100644
index 0000000..04510fb
--- /dev/null
+++ b/ts/constants.ts
@@ -0,0 +1,4 @@
+export const SIZEOF_SHORT = 2;
+export const SIZEOF_INT = 4;
+export const FILE_IDENTIFIER_LENGTH = 4;
+export const SIZE_PREFIX_LENGTH = 4;
\ No newline at end of file
diff --git a/ts/encoding.ts b/ts/encoding.ts
new file mode 100644
index 0000000..856792c
--- /dev/null
+++ b/ts/encoding.ts
@@ -0,0 +1,4 @@
+export enum Encoding {
+    UTF8_BYTES = 1,
+    UTF16_STRING = 2
+}
\ No newline at end of file
diff --git a/ts/flatbuffers.ts b/ts/flatbuffers.ts
new file mode 100644
index 0000000..9184527
--- /dev/null
+++ b/ts/flatbuffers.ts
@@ -0,0 +1,34 @@
+/* eslint-disable @typescript-eslint/no-namespace */
+import * as constants from './constants'
+import * as types from './types'
+import * as utils from './utils'
+
+import { Long as LongClass } from './long'
+import { Encoding as EncodingEnum } from './encoding'
+import { Builder as BuilderClass } from './builder'
+import { ByteBuffer as ByteBufferClass } from './byte-buffer'
+
+export namespace flatbuffers {
+
+    export type Offset = types.Offset;
+
+    export type Table = types.Table;
+
+    export const SIZEOF_SHORT = constants.SIZEOF_SHORT;
+    export const SIZEOF_INT = constants.SIZEOF_INT;
+    export const FILE_IDENTIFIER_LENGTH = constants.FILE_IDENTIFIER_LENGTH;
+    export const SIZE_PREFIX_LENGTH = constants.SIZE_PREFIX_LENGTH;
+
+    export const Encoding = EncodingEnum;
+
+    export const int32 = utils.int32;
+    export const float32 = utils.float32;
+    export const float64 = utils.float64;
+    export const isLittleEndian = utils.isLittleEndian;
+
+    export const Long = LongClass;
+    export const Builder = BuilderClass;
+    export const ByteBuffer = ByteBufferClass;
+}
+
+export default flatbuffers;
diff --git a/ts/flexbuffers.ts b/ts/flexbuffers.ts
new file mode 100644
index 0000000..40482dc
--- /dev/null
+++ b/ts/flexbuffers.ts
@@ -0,0 +1,30 @@
+/* eslint-disable @typescript-eslint/no-namespace */
+import { Builder } from './flexbuffers/builder'
+import { toReference as toReferenceFunction } from './flexbuffers/reference';
+
+export function builder(): Builder {
+    return new Builder();
+}
+
+export function toObject(buffer: Uint8Array): unknown {
+    return toReferenceFunction(buffer).toObject();
+}
+
+export function encode(object: unknown, size = 2048, deduplicateStrings = true, deduplicateKeys = true, deduplicateKeyVectors = true): Uint8Array {
+    const builder = new Builder(size > 0 ? size : 2048, deduplicateStrings, deduplicateKeys, deduplicateKeyVectors);
+    builder.add(object);
+    return builder.finish();
+}
+
+const builderFunction = builder
+const toObjectFunction = toObject
+const encodeFunction = encode
+
+export namespace flexbuffers {
+    export const builder = builderFunction;
+    export const toObject = toObjectFunction;
+    export const encode = encodeFunction;
+    export const toReference = toReferenceFunction;
+}
+
+export default flexbuffers;
diff --git a/ts/flexbuffers/bit-width-util.ts b/ts/flexbuffers/bit-width-util.ts
new file mode 100644
index 0000000..acb3c96
--- /dev/null
+++ b/ts/flexbuffers/bit-width-util.ts
@@ -0,0 +1,34 @@
+import { BitWidth } from './bit-width'
+
+export function toByteWidth(bitWidth: BitWidth): number {
+  return 1 << bitWidth;
+}
+
+export function iwidth(value: number | bigint): BitWidth {
+  if (value >= -128 && value <= 127) return BitWidth.WIDTH8;
+  if (value >= -32768 && value <= 32767) return BitWidth.WIDTH16;
+  if (value >= -2147483648 && value <= 2147483647) return BitWidth.WIDTH32;
+  return BitWidth.WIDTH64;
+}
+
+export function fwidth(value: number): BitWidth {
+  return value === Math.fround(value) ? BitWidth.WIDTH32 : BitWidth.WIDTH64;
+}
+
+export function uwidth(value: number): BitWidth {
+  if (value <= 255) return BitWidth.WIDTH8;
+  if (value <= 65535) return BitWidth.WIDTH16;
+  if (value <= 4294967295) return BitWidth.WIDTH32;
+  return BitWidth.WIDTH64;
+}
+
+export function fromByteWidth(value: number): BitWidth {
+  if (value === 1) return BitWidth.WIDTH8;
+  if (value === 2) return BitWidth.WIDTH16;
+  if (value === 4) return BitWidth.WIDTH32;
+  return BitWidth.WIDTH64;
+}
+
+export function paddingSize(bufSize: number, scalarSize: number): number {
+  return (~bufSize + 1) & (scalarSize - 1);
+}
\ No newline at end of file
diff --git a/ts/flexbuffers/bit-width.ts b/ts/flexbuffers/bit-width.ts
new file mode 100644
index 0000000..5f85b61
--- /dev/null
+++ b/ts/flexbuffers/bit-width.ts
@@ -0,0 +1,6 @@
+export enum BitWidth {
+  WIDTH8 = 0,
+  WIDTH16 = 1,
+  WIDTH32 = 2,
+  WIDTH64 = 3,
+}
\ No newline at end of file
diff --git a/ts/flexbuffers/builder.ts b/ts/flexbuffers/builder.ts
new file mode 100644
index 0000000..4321547
--- /dev/null
+++ b/ts/flexbuffers/builder.ts
@@ -0,0 +1,549 @@
+import { BitWidth } from './bit-width'
+import { paddingSize, iwidth, uwidth, fwidth, toByteWidth, fromByteWidth } from './bit-width-util'
+import { toUTF8Array } from './flexbuffers-util'
+import { ValueType } from './value-type'
+import { isNumber, isTypedVectorElement, toTypedVector } from './value-type-util'
+import { StackValue } from './stack-value'
+
+interface StackPointer {
+  stackPosition: number,
+  isVector: boolean
+  presorted?: boolean
+}
+
+export class Builder {
+  buffer: ArrayBuffer
+  view: DataView
+
+  readonly stack: Array<StackValue> = [];
+  readonly stackPointers: Array<StackPointer> = [];
+  offset = 0;
+  finished = false;
+  readonly stringLookup: Record<string, StackValue> = {};
+  readonly keyLookup: Record<string, StackValue> = {};
+  readonly keyVectorLookup: Record<string, StackValue> = {};
+  readonly indirectIntLookup: Record<number, StackValue> = {};
+  readonly indirectUIntLookup: Record<number, StackValue> = {};
+  readonly indirectFloatLookup: Record<number, StackValue> = {};
+
+  constructor(size = 2048, private dedupStrings = true, private dedupKeys = true, private dedupKeyVectors = true) {
+    this.buffer = new ArrayBuffer(size > 0 ? size : 2048);
+    this.view = new DataView(this.buffer);
+  }
+
+  private align(width: BitWidth) {
+    const byteWidth = toByteWidth(width);
+    this.offset += paddingSize(this.offset, byteWidth);
+    return byteWidth;
+  }
+
+  computeOffset(newValueSize: number): number {
+    const targetOffset = this.offset + newValueSize;
+    let size = this.buffer.byteLength;
+    const prevSize = size;
+    while (size < targetOffset) {
+      size <<= 1;
+    }
+    if (prevSize < size) {
+      const prevBuffer = this.buffer;
+      this.buffer = new ArrayBuffer(size);
+      this.view = new DataView(this.buffer);
+      new Uint8Array(this.buffer).set(new Uint8Array(prevBuffer), 0);
+    }
+    return targetOffset;
+  }
+
+  pushInt(value: number, width: BitWidth): void {
+    if (width === BitWidth.WIDTH8) {
+      this.view.setInt8(this.offset, value);
+    } else if (width === BitWidth.WIDTH16) {
+      this.view.setInt16(this.offset, value, true);
+    } else if (width === BitWidth.WIDTH32) {
+      this.view.setInt32(this.offset, value, true);
+    } else if (width === BitWidth.WIDTH64) {
+      this.view.setBigInt64(this.offset, BigInt(value), true);
+    } else {
+      throw `Unexpected width: ${width} for value: ${value}`;
+    }
+  }
+
+  pushUInt(value: number, width: BitWidth): void {
+    if (width === BitWidth.WIDTH8) {
+      this.view.setUint8(this.offset, value);
+    } else if (width === BitWidth.WIDTH16) {
+      this.view.setUint16(this.offset, value, true);
+    } else if (width === BitWidth.WIDTH32) {
+      this.view.setUint32(this.offset, value, true);
+    } else if (width === BitWidth.WIDTH64) {
+      this.view.setBigUint64(this.offset, BigInt(value), true);
+    } else {
+      throw `Unexpected width: ${width} for value: ${value}`;
+    }
+  }
+
+  private writeInt(value: number, byteWidth: number) {
+    const newOffset = this.computeOffset(byteWidth);
+    this.pushInt(value, fromByteWidth(byteWidth));
+    this.offset = newOffset;
+  }
+
+  private writeUInt(value: number, byteWidth: number) {
+    const newOffset = this.computeOffset(byteWidth);
+    this.pushUInt(value, fromByteWidth(byteWidth));
+    this.offset = newOffset;
+  }
+
+  private writeBlob(arrayBuffer: ArrayBuffer) {
+    const length = arrayBuffer.byteLength;
+    const bitWidth = uwidth(length);
+    const byteWidth = this.align(bitWidth);
+    this.writeUInt(length, byteWidth);
+    const blobOffset = this.offset;
+    const newOffset = this.computeOffset(length);
+    new Uint8Array(this.buffer).set(new Uint8Array(arrayBuffer), blobOffset);
+    this.stack.push(this.offsetStackValue(blobOffset, ValueType.BLOB, bitWidth));
+    this.offset = newOffset;
+  }
+
+  private writeString(str: string): void {
+    if (this.dedupStrings && Object.prototype.hasOwnProperty.call(this.stringLookup, str)) {
+      this.stack.push(this.stringLookup[str]);
+      return;
+    }
+    const utf8 = toUTF8Array(str);
+    const length = utf8.length;
+    const bitWidth = uwidth(length);
+    const byteWidth = this.align(bitWidth);
+    this.writeUInt(length, byteWidth);
+    const stringOffset = this.offset;
+    const newOffset = this.computeOffset(length + 1);
+    new Uint8Array(this.buffer).set(utf8, stringOffset);
+    const stackValue = this.offsetStackValue(stringOffset, ValueType.STRING, bitWidth);
+    this.stack.push(stackValue);
+    if (this.dedupStrings) {
+      this.stringLookup[str] = stackValue;
+    }
+    this.offset = newOffset;
+  }
+
+  private writeKey(str: string): void {
+    if (this.dedupKeys && Object.prototype.hasOwnProperty.call(this.keyLookup, str)) {
+      this.stack.push(this.keyLookup[str]);
+      return;
+    }
+    const utf8 = toUTF8Array(str);
+    const length = utf8.length;
+    const newOffset = this.computeOffset(length + 1);
+    new Uint8Array(this.buffer).set(utf8, this.offset);
+    const stackValue = this.offsetStackValue(this.offset, ValueType.KEY, BitWidth.WIDTH8);
+    this.stack.push(stackValue);
+    if (this.dedupKeys) {
+      this.keyLookup[str] = stackValue;
+    }
+    this.offset = newOffset;
+  }
+
+  private writeStackValue(value: StackValue, byteWidth: number): void {
+    const newOffset = this.computeOffset(byteWidth);
+    if (value.isOffset()) {
+      const relativeOffset = this.offset - value.offset;
+      if (byteWidth === 8 || BigInt(relativeOffset) < (BigInt(1) << BigInt(byteWidth * 8))) {
+        this.writeUInt(relativeOffset, byteWidth);
+      } else {
+        throw `Unexpected size ${byteWidth}. This might be a bug. Please create an issue https://github.com/google/flatbuffers/issues/new`
+      }
+    } else {
+      value.writeToBuffer(byteWidth);
+    }
+    this.offset = newOffset;
+  }
+
+  private integrityCheckOnValueAddition() {
+    if (this.finished) {
+      throw "Adding values after finish is prohibited";
+    }
+    if (this.stackPointers.length !== 0 && this.stackPointers[this.stackPointers.length - 1].isVector === false) {
+      if (this.stack[this.stack.length - 1].type !== ValueType.KEY) {
+        throw "Adding value to a map before adding a key is prohibited";
+      }
+    }
+  }
+
+  private integrityCheckOnKeyAddition() {
+    if (this.finished) {
+      throw "Adding values after finish is prohibited";
+    }
+    if (this.stackPointers.length === 0 || this.stackPointers[this.stackPointers.length - 1].isVector) {
+      throw "Adding key before starting a map is prohibited";
+    }
+  }
+
+  startVector(): void {
+    this.stackPointers.push({ stackPosition: this.stack.length, isVector: true });
+  }
+
+  startMap(presorted = false): void {
+    this.stackPointers.push({ stackPosition: this.stack.length, isVector: false, presorted: presorted });
+  }
+
+  private endVector(stackPointer: StackPointer) {
+    const vecLength = this.stack.length - stackPointer.stackPosition;
+    const vec = this.createVector(stackPointer.stackPosition, vecLength, 1);
+    this.stack.splice(stackPointer.stackPosition, vecLength);
+    this.stack.push(vec);
+  }
+
+  private endMap(stackPointer: StackPointer) {
+    if (!stackPointer.presorted) {
+      this.sort(stackPointer);
+    }
+    let keyVectorHash = "";
+    for (let i = stackPointer.stackPosition; i < this.stack.length; i += 2) {
+      keyVectorHash += `,${this.stack[i].offset}`;
+    }
+    const vecLength = (this.stack.length - stackPointer.stackPosition) >> 1;
+
+    if (this.dedupKeyVectors && !Object.prototype.hasOwnProperty.call(this.keyVectorLookup, keyVectorHash)) {
+      this.keyVectorLookup[keyVectorHash] = this.createVector(stackPointer.stackPosition, vecLength, 2);
+    }
+    const keysStackValue = this.dedupKeyVectors ? this.keyVectorLookup[keyVectorHash] : this.createVector(stackPointer.stackPosition, vecLength, 2);
+    const valuesStackValue = this.createVector(stackPointer.stackPosition + 1, vecLength, 2, keysStackValue);
+    this.stack.splice(stackPointer.stackPosition, vecLength << 1);
+    this.stack.push(valuesStackValue);
+  }
+
+  private sort(stackPointer: StackPointer) {
+    const view = this.view
+    const stack = this.stack
+
+    function shouldFlip(v1: StackValue, v2: StackValue) {
+      if (v1.type !== ValueType.KEY || v2.type !== ValueType.KEY) {
+        throw `Stack values are not keys ${v1} | ${v2}. Check if you combined [addKey] with add... method calls properly.`
+      }
+      let c1, c2;
+      let index = 0;
+      do {
+        c1 = view.getUint8(v1.offset + index);
+        c2 = view.getUint8(v2.offset + index);
+        if (c2 < c1) return true;
+        if (c1 < c2) return false;
+        index += 1;
+      } while (c1 !== 0 && c2 !== 0);
+      return false;
+    }
+
+    function swap(stack: Array<StackValue>, flipIndex: number, i: number) {
+      if (flipIndex === i) return;
+      const k = stack[flipIndex];
+      const v = stack[flipIndex + 1];
+      stack[flipIndex] = stack[i];
+      stack[flipIndex + 1] = stack[i + 1];
+      stack[i] = k;
+      stack[i + 1] = v;
+    }
+
+    function selectionSort() {
+      for (let i = stackPointer.stackPosition; i < stack.length; i += 2) {
+        let flipIndex = i;
+        for (let j = i + 2; j < stack.length; j += 2) {
+          if (shouldFlip(stack[flipIndex], stack[j])) {
+            flipIndex = j;
+          }
+        }
+        if (flipIndex !== i) {
+          swap(stack, flipIndex, i);
+        }
+      }
+    }
+
+    function smaller(v1: StackValue, v2: StackValue) {
+      if (v1.type !== ValueType.KEY || v2.type !== ValueType.KEY) {
+        throw `Stack values are not keys ${v1} | ${v2}. Check if you combined [addKey] with add... method calls properly.`
+      }
+      if (v1.offset === v2.offset) {
+        return false;
+      }
+      let c1, c2;
+      let index = 0;
+      do {
+        c1 = view.getUint8(v1.offset + index);
+        c2 = view.getUint8(v2.offset + index);
+        if (c1 < c2) return true;
+        if (c2 < c1) return false;
+        index += 1;
+      } while (c1 !== 0 && c2 !== 0);
+      return false;
+    }
+
+    function quickSort(left: number, right: number) {
+
+      if (left < right) {
+        const mid = left + (((right - left) >> 2)) * 2;
+        const pivot = stack[mid];
+        let left_new = left;
+        let right_new = right;
+
+        do {
+          while (smaller(stack[left_new], pivot)) {
+            left_new += 2;
+          }
+          while (smaller(pivot, stack[right_new])) {
+            right_new -= 2;
+          }
+          if (left_new <= right_new) {
+            swap(stack, left_new, right_new);
+            left_new += 2;
+            right_new -= 2;
+          }
+        } while (left_new <= right_new);
+
+        quickSort(left, right_new);
+        quickSort(left_new, right);
+
+      }
+    }
+
+    let sorted = true;
+    for (let i = stackPointer.stackPosition; i < this.stack.length - 2; i += 2) {
+      if (shouldFlip(this.stack[i], this.stack[i + 2])) {
+        sorted = false;
+        break;
+      }
+    }
+
+    if (!sorted) {
+      if (this.stack.length - stackPointer.stackPosition > 40) {
+        quickSort(stackPointer.stackPosition, this.stack.length - 2);
+      } else {
+        selectionSort();
+      }
+    }
+  }
+
+  end(): void {
+    if (this.stackPointers.length < 1) return;
+    const pointer = this.stackPointers.pop() as StackPointer;
+    if (pointer.isVector) {
+      this.endVector(pointer);
+    } else {
+      this.endMap(pointer);
+    }
+  }
+
+  private createVector(start: number, vecLength: number, step: number, keys: StackValue | null = null) {
+    let bitWidth = uwidth(vecLength);
+    let prefixElements = 1;
+    if (keys !== null) {
+      const elementWidth = keys.elementWidth(this.offset, 0);
+      if (elementWidth > bitWidth) {
+        bitWidth = elementWidth;
+      }
+      prefixElements += 2;
+    }
+    let vectorType = ValueType.KEY;
+    let typed = keys === null;
+    for (let i = start; i < this.stack.length; i += step) {
+      const elementWidth = this.stack[i].elementWidth(this.offset, i + prefixElements);
+      if (elementWidth > bitWidth) {
+        bitWidth = elementWidth;
+      }
+      if (i === start) {
+        vectorType = this.stack[i].type;
+        typed = typed && isTypedVectorElement(vectorType);
+      } else {
+        if (vectorType !== this.stack[i].type) {
+          typed = false;
+        }
+      }
+    }
+    const byteWidth = this.align(bitWidth);
+    const fix = typed && isNumber(vectorType) && vecLength >= 2 && vecLength <= 4;
+    if (keys !== null) {
+      this.writeStackValue(keys, byteWidth);
+      this.writeUInt(1 << keys.width, byteWidth);
+    }
+    if (!fix) {
+      this.writeUInt(vecLength, byteWidth);
+    }
+    const vecOffset = this.offset;
+    for (let i = start; i < this.stack.length; i += step) {
+      this.writeStackValue(this.stack[i], byteWidth);
+    }
+    if (!typed) {
+      for (let i = start; i < this.stack.length; i += step) {
+        this.writeUInt(this.stack[i].storedPackedType(), 1);
+      }
+    }
+    if (keys !== null) {
+      return this.offsetStackValue(vecOffset, ValueType.MAP, bitWidth);
+    }
+    if (typed) {
+      const vType = toTypedVector(vectorType, fix ? vecLength : 0);
+      return this.offsetStackValue(vecOffset, vType, bitWidth);
+    }
+    return this.offsetStackValue(vecOffset, ValueType.VECTOR, bitWidth);
+  }
+
+  private nullStackValue() {
+    return new StackValue(this, ValueType.NULL, BitWidth.WIDTH8);
+  }
+
+  private boolStackValue(value: boolean) {
+    return new StackValue(this, ValueType.BOOL, BitWidth.WIDTH8, value);
+  }
+
+  private intStackValue(value: number | bigint) {
+    return new StackValue(this, ValueType.INT, iwidth(value), value as number);
+  }
+
+  private uintStackValue(value: number) {
+    return new StackValue(this, ValueType.UINT, uwidth(value), value);
+  }
+
+  private floatStackValue(value: number) {
+    return new StackValue(this, ValueType.FLOAT, fwidth(value), value);
+  }
+
+  private offsetStackValue(offset: number, valueType: ValueType, bitWidth: BitWidth): StackValue {
+    return new StackValue(this, valueType, bitWidth, null, offset);
+  }
+
+  private finishBuffer() {
+    if (this.stack.length !== 1) {
+      throw `Stack has to be exactly 1, but it is ${this.stack.length}. You have to end all started vectors and maps before calling [finish]`;
+    }
+    const value = this.stack[0];
+    const byteWidth = this.align(value.elementWidth(this.offset, 0));
+    this.writeStackValue(value, byteWidth);
+    this.writeUInt(value.storedPackedType(), 1);
+    this.writeUInt(byteWidth, 1);
+    this.finished = true;
+  }
+
+  add(value: undefined | null | boolean | bigint | number | DataView | string | Array<unknown> | Record<string, unknown> | unknown): void {
+    this.integrityCheckOnValueAddition();
+    if (typeof value === 'undefined') {
+      throw "You need to provide a value";
+    }
+    if (value === null) {
+      this.stack.push(this.nullStackValue());
+    } else if (typeof value === "boolean") {
+      this.stack.push(this.boolStackValue(value));
+    } else if (typeof value === "bigint") {
+      this.stack.push(this.intStackValue(value));
+    } else if (typeof value == 'number') {
+      if (Number.isInteger(value)) {
+        this.stack.push(this.intStackValue(value));
+      } else {
+        this.stack.push(this.floatStackValue(value));
+      }
+    } else if (ArrayBuffer.isView(value)) {
+      this.writeBlob(value.buffer);
+    } else if (typeof value === 'string' || value instanceof String) {
+      this.writeString(value as string);
+    } else if (Array.isArray(value)) {
+      this.startVector();
+      for (let i = 0; i < value.length; i++) {
+        this.add(value[i]);
+      }
+      this.end();
+    } else if (typeof value === 'object') {
+      const properties = Object.getOwnPropertyNames(value).sort();
+      this.startMap(true);
+      for (let i = 0; i < properties.length; i++) {
+        const key = properties[i];
+        this.addKey(key);
+        this.add((value as Record<string, unknown>)[key]);
+      }
+      this.end();
+    } else {
+      throw `Unexpected value input ${value}`;
+    }
+  }
+
+  finish(): Uint8Array {
+    if (!this.finished) {
+      this.finishBuffer();
+    }
+    const result = this.buffer.slice(0, this.offset);
+    return new Uint8Array(result);
+  }
+
+  isFinished(): boolean {
+    return this.finished;
+  }
+
+  addKey(key: string): void {
+    this.integrityCheckOnKeyAddition();
+    this.writeKey(key);
+  }
+
+  addInt(value: number, indirect = false, deduplicate = false): void {
+    this.integrityCheckOnValueAddition();
+    if (!indirect) {
+      this.stack.push(this.intStackValue(value));
+      return;
+    }
+    if (deduplicate && Object.prototype.hasOwnProperty.call(this.indirectIntLookup, value)) {
+      this.stack.push(this.indirectIntLookup[value]);
+      return;
+    }
+    const stackValue = this.intStackValue(value);
+    const byteWidth = this.align(stackValue.width);
+    const newOffset = this.computeOffset(byteWidth);
+    const valueOffset = this.offset;
+    stackValue.writeToBuffer(byteWidth);
+    const stackOffset = this.offsetStackValue(valueOffset, ValueType.INDIRECT_INT, stackValue.width);
+    this.stack.push(stackOffset);
+    this.offset = newOffset;
+    if (deduplicate) {
+      this.indirectIntLookup[value] = stackOffset;
+    }
+  }
+
+  addUInt(value: number, indirect = false, deduplicate = false): void {
+    this.integrityCheckOnValueAddition();
+    if (!indirect) {
+      this.stack.push(this.uintStackValue(value));
+      return;
+    }
+    if (deduplicate && Object.prototype.hasOwnProperty.call(this.indirectUIntLookup, value)) {
+      this.stack.push(this.indirectUIntLookup[value]);
+      return;
+    }
+    const stackValue = this.uintStackValue(value);
+    const byteWidth = this.align(stackValue.width);
+    const newOffset = this.computeOffset(byteWidth);
+    const valueOffset = this.offset;
+    stackValue.writeToBuffer(byteWidth);
+    const stackOffset = this.offsetStackValue(valueOffset, ValueType.INDIRECT_UINT, stackValue.width);
+    this.stack.push(stackOffset);
+    this.offset = newOffset;
+    if (deduplicate) {
+      this.indirectUIntLookup[value] = stackOffset;
+    }
+  }
+
+  addFloat(value: number, indirect = false, deduplicate = false): void {
+    this.integrityCheckOnValueAddition();
+    if (!indirect) {
+      this.stack.push(this.floatStackValue(value));
+      return;
+    }
+    if (deduplicate && Object.prototype.hasOwnProperty.call(this.indirectFloatLookup, value)) {
+      this.stack.push(this.indirectFloatLookup[value]);
+      return;
+    }
+    const stackValue = this.floatStackValue(value);
+    const byteWidth = this.align(stackValue.width);
+    const newOffset = this.computeOffset(byteWidth);
+    const valueOffset = this.offset;
+    stackValue.writeToBuffer(byteWidth);
+    const stackOffset = this.offsetStackValue(valueOffset, ValueType.INDIRECT_FLOAT, stackValue.width);
+    this.stack.push(stackOffset);
+    this.offset = newOffset;
+    if (deduplicate) {
+      this.indirectFloatLookup[value] = stackOffset;
+    }
+  }
+}
diff --git a/ts/flexbuffers/flexbuffers-util.ts b/ts/flexbuffers/flexbuffers-util.ts
new file mode 100644
index 0000000..83186e9
--- /dev/null
+++ b/ts/flexbuffers/flexbuffers-util.ts
@@ -0,0 +1,9 @@
+export function fromUTF8Array(data: BufferSource): string {
+  const decoder = new TextDecoder();
+  return decoder.decode(data);
+}
+
+export function toUTF8Array(str: string) : Uint8Array {
+  const encoder = new TextEncoder();
+  return encoder.encode(str);
+}
\ No newline at end of file
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
diff --git a/ts/flexbuffers/reference.ts b/ts/flexbuffers/reference.ts
new file mode 100644
index 0000000..a93c743
--- /dev/null
+++ b/ts/flexbuffers/reference.ts
@@ -0,0 +1,185 @@
+import { fromByteWidth } from './bit-width-util'
+import { ValueType } from './value-type'
+import { isNumber, isIndirectNumber, isAVector, fixedTypedVectorElementSize, isFixedTypedVector, isTypedVector, typedVectorElementType, packedType, fixedTypedVectorElementType } from './value-type-util'
+import { indirect, keyForIndex, keyIndex, readFloat, readInt, readUInt, valueForIndexWithKey } from './reference-util'
+import { Long } from '../long';
+import { fromUTF8Array } from './flexbuffers-util';
+import { BitWidth } from './bit-width';
+
+export function toReference(buffer: Uint8Array): Reference {
+  const len = buffer.byteLength;
+  
+  if (len < 3) {
+    throw "Buffer needs to be bigger than 3";
+  }
+
+  const dataView = new DataView(buffer);
+  const byteWidth = dataView.getUint8(len - 1);
+  const packedType = dataView.getUint8(len - 2);
+  const parentWidth = fromByteWidth(byteWidth);
+  const offset = len - byteWidth - 2;
+
+  return new Reference(dataView, offset, parentWidth, packedType, "/")
+}
+
+export class Reference {
+  private readonly byteWidth: number
+  private readonly valueType: ValueType
+  private _length = -1
+  constructor(private dataView: DataView, private offset: number, private parentWidth: number, private packedType: ValueType, private path: string) {
+    this.byteWidth = 1 << (packedType & 3)
+    this.valueType = packedType >> 2
+  }
+
+  isNull(): boolean { return this.valueType === ValueType.NULL; }
+  isNumber(): boolean { return isNumber(this.valueType) || isIndirectNumber(this.valueType); }
+  isFloat(): boolean { return ValueType.FLOAT === this.valueType || ValueType.INDIRECT_FLOAT === this.valueType; }
+  isInt(): boolean { return this.isNumber() && !this.isFloat(); }
+  isString(): boolean { return ValueType.STRING === this.valueType || ValueType.KEY === this.valueType; }
+  isBool(): boolean { return ValueType.BOOL === this.valueType; }
+  isBlob(): boolean { return ValueType.BLOB === this.valueType; }
+  isVector(): boolean { return isAVector(this.valueType); }
+  isMap(): boolean { return ValueType.MAP === this.valueType; }
+
+  boolValue(): boolean | null {
+    if (this.isBool()) {
+      return readInt(this.dataView, this.offset, this.parentWidth) > 0;
+    }
+    return null;
+  }
+
+  intValue(): number | Long | bigint | null {
+    if (this.valueType === ValueType.INT) {
+      return readInt(this.dataView, this.offset, this.parentWidth);
+    }
+    if (this.valueType === ValueType.UINT) {
+      return readUInt(this.dataView, this.offset, this.parentWidth);
+    }
+    if (this.valueType === ValueType.INDIRECT_INT) {
+      return readInt(this.dataView, indirect(this.dataView, this.offset, this.parentWidth), fromByteWidth(this.byteWidth));
+    }
+    if (this.valueType === ValueType.INDIRECT_UINT) {
+      return readUInt(this.dataView, indirect(this.dataView, this.offset, this.parentWidth), fromByteWidth(this.byteWidth));
+    }
+    return null;
+  }
+
+  floatValue(): number | null {
+    if (this.valueType === ValueType.FLOAT) {
+      return readFloat(this.dataView, this.offset, this.parentWidth);
+    }
+    if (this.valueType === ValueType.INDIRECT_FLOAT) {
+      return readFloat(this.dataView, indirect(this.dataView, this.offset, this.parentWidth), fromByteWidth(this.byteWidth));
+    }
+    return null;
+  }
+
+  numericValue(): number | Long | bigint | null { return this.floatValue() || this.intValue()}
+
+  stringValue(): string | null {
+    if (this.valueType === ValueType.STRING || this.valueType === ValueType.KEY) {
+      const begin = indirect(this.dataView, this.offset, this.parentWidth);
+      return fromUTF8Array(new Uint8Array(this.dataView.buffer, begin, this.length()));
+    }
+    return null;
+  }
+
+  blobValue(): Uint8Array | null {
+    if (this.isBlob()) {
+      const begin = indirect(this.dataView, this.offset, this.parentWidth);
+      return new Uint8Array(this.dataView.buffer, begin, this.length());
+    }
+    return null;
+  }
+
+  get(key: number): Reference {
+    const length = this.length();
+    if (Number.isInteger(key) && isAVector(this.valueType)) {
+      if (key >= length || key < 0) {
+        throw `Key: [${key}] is not applicable on ${this.path} of ${this.valueType} length: ${length}`;
+      }
+      const _indirect = indirect(this.dataView, this.offset, this.parentWidth);
+      const elementOffset = _indirect + key * this.byteWidth;
+      let _packedType = this.dataView.getUint8(_indirect + length * this.byteWidth + key);
+      if (isTypedVector(this.valueType)) {
+        const _valueType = typedVectorElementType(this.valueType);
+        _packedType = packedType(_valueType, BitWidth.WIDTH8);
+      } else if (isFixedTypedVector(this.valueType)) {
+        const _valueType = fixedTypedVectorElementType(this.valueType);
+        _packedType = packedType(_valueType, BitWidth.WIDTH8);
+      }
+      return new Reference(this.dataView, elementOffset, fromByteWidth(this.byteWidth), _packedType, `${this.path}[${key}]`);
+    }
+    if (typeof key === 'string') {
+      const index = keyIndex(key, this.dataView, this.offset, this.parentWidth, this.byteWidth, length);
+      if (index !== null) {
+        return valueForIndexWithKey(index, key, this.dataView, this.offset, this.parentWidth, this.byteWidth, length, this.path)
+      }
+    }
+    throw `Key [${key}] is not applicable on ${this.path} of ${this.valueType}`;
+  }
+
+  length(): number {
+    let size;
+    if (this._length > -1) {
+      return this._length;
+    }
+    if (isFixedTypedVector(this.valueType)) {
+      this._length = fixedTypedVectorElementSize(this.valueType);
+    } else if (this.valueType === ValueType.BLOB
+      || this.valueType === ValueType.MAP
+      || isAVector(this.valueType)) {
+      this._length = readUInt(this.dataView, indirect(this.dataView, this.offset, this.parentWidth) - this.byteWidth, fromByteWidth(this.byteWidth)) as number
+    } else if (this.valueType === ValueType.NULL) {
+      this._length = 0;
+    } else if (this.valueType === ValueType.STRING) {
+      const _indirect = indirect(this.dataView, this.offset, this.parentWidth);
+      let sizeByteWidth = this.byteWidth;
+      size = readUInt(this.dataView, _indirect - sizeByteWidth, fromByteWidth(this.byteWidth));
+      while (this.dataView.getInt8(_indirect + (size as number)) !== 0) {
+        sizeByteWidth <<= 1;
+        size = readUInt(this.dataView, _indirect - sizeByteWidth, fromByteWidth(this.byteWidth));
+      }
+      this._length = size as number;
+    } else if (this.valueType === ValueType.KEY) {
+      const _indirect = indirect(this.dataView, this.offset, this.parentWidth);
+      size = 1;
+      while (this.dataView.getInt8(_indirect + size) !== 0) {
+        size++;
+      }
+      this._length = size;
+    } else {
+      this._length = 1;
+    }
+    return this._length;
+  }
+
+  toObject(): unknown {
+    const length = this.length();
+    if (this.isVector()) {
+      const result = [];
+      for (let i = 0; i < length; i++) {
+        result.push(this.get(i).toObject());
+      }
+      return result;
+    }
+    if (this.isMap()) {
+      const result: Record<string, unknown> = {};
+      for (let i = 0; i < length; i++) {
+        const key = keyForIndex(i, this.dataView, this.offset, this.parentWidth, this.byteWidth);
+        result[key] = valueForIndexWithKey(i, key, this.dataView, this.offset, this.parentWidth, this.byteWidth, length, this.path).toObject();
+      }
+      return result;
+    }
+    if (this.isNull()) {
+      return null;
+    }
+    if (this.isBool()) {
+      return this.boolValue();
+    }
+    if (this.isNumber()) {
+      return this.numericValue();
+    }
+    return this.blobValue() || this.stringValue();
+  }
+}
diff --git a/ts/flexbuffers/stack-value.ts b/ts/flexbuffers/stack-value.ts
new file mode 100644
index 0000000..ef8e2f1
--- /dev/null
+++ b/ts/flexbuffers/stack-value.ts
@@ -0,0 +1,61 @@
+import { Builder } from './builder'
+import { BitWidth } from './bit-width'
+import { paddingSize, uwidth, fromByteWidth } from './bit-width-util'
+import { ValueType } from './value-type'
+import { isInline, packedType } from './value-type-util'
+
+export class StackValue {
+  constructor(private builder: Builder, public type: ValueType, public width: number, public value: number | boolean | null = null, public offset: number = 0) {
+
+  }
+
+  elementWidth(size: number, index: number): BitWidth {
+    if (isInline(this.type)) return this.width;
+    for (let i = 0; i < 4; i++) {
+      const width = 1 << i;
+      const offsetLoc = size + paddingSize(size, width) + index * width;
+      const offset = offsetLoc - this.offset;
+      const bitWidth = uwidth(offset);
+      if (1 << bitWidth === width) {
+        return bitWidth;
+      }
+    }
+    throw `Element is unknown. Size: ${size} at index: ${index}. This might be a bug. Please create an issue https://github.com/google/flatbuffers/issues/new`;
+  }
+
+  writeToBuffer(byteWidth: number): void {
+    const newOffset = this.builder.computeOffset(byteWidth);
+    if (this.type === ValueType.FLOAT) {
+      if (this.width === BitWidth.WIDTH32) {
+        this.builder.view.setFloat32(this.builder.offset, this.value as number, true);
+      } else {
+        this.builder.view.setFloat64(this.builder.offset, this.value as number, true);
+      }
+    } else if (this.type === ValueType.INT) {
+      const bitWidth = fromByteWidth(byteWidth);
+      this.builder.pushInt(this.value as number, bitWidth);
+    } else if (this.type === ValueType.UINT) {
+      const bitWidth = fromByteWidth(byteWidth);
+      this.builder.pushUInt(this.value as number, bitWidth);
+    } else if (this.type === ValueType.NULL) {
+      this.builder.pushInt(0, this.width);
+    } else if (this.type === ValueType.BOOL) {
+      this.builder.pushInt(this.value ? 1 : 0, this.width);
+    } else {
+      throw `Unexpected type: ${this.type}. This might be a bug. Please create an issue https://github.com/google/flatbuffers/issues/new`
+    }
+    this.offset = newOffset;
+  }
+
+  storedWidth(width = BitWidth.WIDTH8): BitWidth {
+    return isInline(this.type) ? Math.max(width, this.width) : this.width;
+  }
+
+  storedPackedType(width = BitWidth.WIDTH8): ValueType {
+    return packedType(this.type, this.storedWidth(width));
+  }
+
+  isOffset(): boolean {
+    return !isInline(this.type)
+  }
+}
\ No newline at end of file
diff --git a/ts/flexbuffers/value-type-util.ts b/ts/flexbuffers/value-type-util.ts
new file mode 100644
index 0000000..da869a9
--- /dev/null
+++ b/ts/flexbuffers/value-type-util.ts
@@ -0,0 +1,64 @@
+import { ValueType } from './value-type'
+
+export function isInline(value: ValueType): boolean {
+  return value === ValueType.BOOL
+    || value <= ValueType.FLOAT;
+}
+
+export function isNumber(value: ValueType): boolean {
+  return value >= ValueType.INT
+    && value <= ValueType.FLOAT;
+}
+
+export function isIndirectNumber(value: ValueType): boolean {
+  return value >= ValueType.INDIRECT_INT
+    && value <= ValueType.INDIRECT_FLOAT;
+}
+
+export function isTypedVectorElement(value: ValueType): boolean {
+  return value === ValueType.BOOL
+    || (value >= ValueType.INT
+      && value <= ValueType.STRING);
+}
+
+export function isTypedVector(value: ValueType): boolean {
+  return value === ValueType.VECTOR_BOOL
+    || (value >= ValueType.VECTOR_INT
+      && value <= ValueType.VECTOR_STRING_DEPRECATED);
+}
+
+export function isFixedTypedVector(value: ValueType): boolean {
+  return value >= ValueType.VECTOR_INT2
+    && value <= ValueType.VECTOR_FLOAT4;
+}
+
+export function isAVector(value: ValueType): boolean {
+  return isTypedVector(value)
+    || isFixedTypedVector(value)
+    || value === ValueType.VECTOR;
+}
+
+export function toTypedVector(valueType: ValueType, length: number): ValueType {
+  if (length === 0) return valueType - ValueType.INT + ValueType.VECTOR_INT;
+  if (length === 2) return valueType - ValueType.INT + ValueType.VECTOR_INT2;
+  if (length === 3) return valueType - ValueType.INT + ValueType.VECTOR_INT3;
+  if (length === 4) return valueType - ValueType.INT + ValueType.VECTOR_INT4;
+  throw "Unexpected length " + length;
+}
+
+export function typedVectorElementType(valueType: ValueType): ValueType {
+  return valueType - ValueType.VECTOR_INT + ValueType.INT;
+}
+
+export function fixedTypedVectorElementType(valueType: ValueType): ValueType {
+  return ((valueType - ValueType.VECTOR_INT2) % 3) + ValueType.INT;
+}
+
+export function fixedTypedVectorElementSize(valueType: ValueType): ValueType {
+  // The x / y >> 0 trick is to have an int division. Suppose to be faster than Math.floor()
+  return (((valueType - ValueType.VECTOR_INT2) / 3) >> 0) + 2;
+}
+
+export function packedType(valueType: ValueType, bitWidth: number): ValueType {
+  return bitWidth | (valueType << 2);
+}
\ No newline at end of file
diff --git a/ts/flexbuffers/value-type.ts b/ts/flexbuffers/value-type.ts
new file mode 100644
index 0000000..9c88ba2
--- /dev/null
+++ b/ts/flexbuffers/value-type.ts
@@ -0,0 +1,30 @@
+export enum ValueType {
+  NULL = 0,
+  INT = 1,
+  UINT = 2,
+  FLOAT = 3,
+  KEY = 4,
+  STRING = 5,
+  INDIRECT_INT = 6,
+  INDIRECT_UINT = 7,
+  INDIRECT_FLOAT = 8,
+  MAP = 9,
+  VECTOR = 10,
+  VECTOR_INT = 11,
+  VECTOR_UINT = 12,
+  VECTOR_FLOAT = 13,
+  VECTOR_KEY = 14,
+  VECTOR_STRING_DEPRECATED = 15,
+  VECTOR_INT2 = 16,
+  VECTOR_UINT2 = 17,
+  VECTOR_FLOAT2 = 18,
+  VECTOR_INT3 = 19,
+  VECTOR_UINT3 = 20,
+  VECTOR_FLOAT3 = 21,
+  VECTOR_INT4 = 22,
+  VECTOR_UINT4 = 23,
+  VECTOR_FLOAT4 = 24,
+  BLOB = 25,
+  BOOL = 26,
+  VECTOR_BOOL = 36,
+}
\ No newline at end of file
diff --git a/ts/long.ts b/ts/long.ts
new file mode 100644
index 0000000..50a3ea8
--- /dev/null
+++ b/ts/long.ts
@@ -0,0 +1,23 @@
+export function createLong(low: number, high: number): Long {
+    return Long.create(low, high);
+}
+  
+export class Long {
+    static readonly ZERO = new Long(0, 0)
+    low: number
+    high: number
+    constructor(low: number, high: number) {
+        this.low = low | 0;
+        this.high = high | 0;
+    }
+    static create(low: number, high: number): Long {
+        // Special-case zero to avoid GC overhead for default values
+        return low == 0 && high == 0 ? Long.ZERO : new Long(low, high);
+    }
+    toFloat64(): number {
+        return (this.low >>> 0) + this.high * 0x100000000;
+    }
+    equals(other: Long): boolean {
+        return this.low == other.low && this.high == other.high;
+    }
+}
\ No newline at end of file
diff --git a/ts/types.ts b/ts/types.ts
new file mode 100644
index 0000000..30e4050
--- /dev/null
+++ b/ts/types.ts
@@ -0,0 +1,14 @@
+import { ByteBuffer } from './byte-buffer'
+import { Builder } from './builder'
+
+export type Offset = number;
+
+export type Table = {
+  bb: ByteBuffer
+  bb_pos: number
+};
+
+export interface IGeneratedObject {
+  pack(builder:Builder): Offset
+  unpack(): IGeneratedObject
+}
\ No newline at end of file
diff --git a/ts/utils.ts b/ts/utils.ts
new file mode 100644
index 0000000..a2902e3
--- /dev/null
+++ b/ts/utils.ts
@@ -0,0 +1,4 @@
+export const int32 = new Int32Array(2);
+export const float32 = new Float32Array(int32.buffer);
+export const float64 = new Float64Array(int32.buffer);
+export const isLittleEndian = new Uint16Array(new Uint8Array([1, 0]).buffer)[0] === 1;
\ No newline at end of file
