diff --git a/nim/flatbuffers/src/builder.nim b/nim/flatbuffers/src/builder.nim
new file mode 100644
index 0000000..62ac2ed
--- /dev/null
+++ b/nim/flatbuffers/src/builder.nim
@@ -0,0 +1,262 @@
+import math
+import table
+
+
+const MAX_BUFFER_SIZE* = 2^31
+
+
+type Builder* = ref object of RootObj
+   bytes*: seq[byte]
+   minalign*: int
+   current_vtable*: seq[uoffset]
+   objectEnd*: uoffset
+   vtables*: seq[uoffset] #?
+   head*: uoffset
+   nested*: bool
+   finished*: bool
+   vectorNumElems*: uoffset
+
+using this: var Builder
+
+func newBuilder*(size: int): Builder =
+   result = new Builder
+   result.bytes.setLen(size)
+   result.minalign = 1
+   result.head = size.uoffset
+   result.nested = false
+   result.finished = false
+   result.vectorNumElems = 0
+
+proc FinishedBytes*(this): seq[byte] =
+   if not this.finished:
+      quit("Builder not finished, Incorrect use of FinishedBytes(): must call 'Finish' first.")
+   result = this.bytes[this.head..^1]
+
+proc Output*(this): seq[byte] =
+   if not this.finished:
+      quit("Builder not finished, Incorrect use of Output(): must call 'Finish' first.")
+
+   result = this.bytes[this.head..^1]
+
+func Offset*(this): uoffset =
+   result = this.bytes.len.uoffset - this.head
+
+proc StartObject*(this; numfields: int) =
+   if this.nested:
+      quit("builder is nested")
+
+   this.current_vtable.setLen(numfields)
+   for i in this.current_vtable.mitems():
+      i = 0
+   this.objectEnd = this.Offset()
+   this.nested = true
+
+proc GrowByteBuffer*(this) =
+   if this.bytes.len == MAX_BUFFER_SIZE:
+      quit("flatbuffers: cannot grow buffer beyond 2 gigabytes")
+   let oldLen = this.bytes.len
+   var newLen = min(this.bytes.len * 2, MAX_BUFFER_SIZE)
+   if newLen == 0:
+      newLen = 1
+   this.bytes.setLen(newLen)
+   var j = this.bytes.len - 1
+   while j >= 0:
+      if j >= newLen - oldLen:
+         this.bytes[j] = this.bytes[j - (newLen - oldLen)]
+      else:
+         this.bytes[j] = 0
+      dec(j)
+
+proc Place*[T](this; x: T) =
+   this.head -= uoffset x.sizeof
+   WriteVal(this.bytes, this.head, x)
+
+func Pad*(this; n: int) =
+   for i in 0..<n:
+      this.Place(0.byte)
+
+proc Prep*(this; size: int; additionalBytes: int) =
+   if size > this.minalign:
+      this.minalign = size
+   var alignsize = (not (this.bytes.len - this.head.int + additionalBytes)) + 1
+   alignsize = alignsize and (size - 1)
+
+   while this.head.int < alignsize + size + additionalBytes:
+      let oldbufSize = this.bytes.len
+      this.GrowByteBuffer()
+      this.head = (this.head.int + this.bytes.len - oldbufSize).uoffset
+   this.Pad(alignsize)
+
+proc PrependOffsetRelative*[T: Offsets](this; off: T) =
+   when T is voffset:
+      this.Prep(T.sizeof, 0)
+      if not off.uoffset <= this.Offset:
+         quit("flatbuffers: Offset arithmetic error.")
+      this.Place(off)
+   else:
+      this.Prep(T.sizeof, 0)
+      if not off.uoffset <= this.Offset:
+         quit("flatbuffers: Offset arithmetic error.")
+      let off2: T = this.Offset.T - off + sizeof(T).T
+      this.Place(off2)
+
+
+proc Prepend*[T](this; x: T) =
+   this.Prep(x.sizeof, 0)
+   this.Place(x)
+
+proc Slot*(this; slotnum: int) =
+   this.current_vtable[slotnum] = this.Offset
+
+proc PrependSlot*[T](this; o: int; x, d: T) =
+   if x != d:
+      when T is uoffset or T is soffset or T is voffset:
+         this.PrependOffsetRelative(x)
+      else:
+         this.Prepend(x)
+      this.Slot(o)
+
+proc AssertStuctInline(this; obj: uoffset) =
+   if obj != this.Offset:
+      quit("flatbuffers: Tried to write a Struct at an Offset that is different from the current Offset of the Builder.")
+
+proc PrependStructSlot*(this; o: int; x: uoffset; d: uoffset) =
+   if x != d:
+      this.AssertStuctInline(x)
+      this.Slot(o)
+
+proc Add*[T](this; n: T) =
+   this.Prep(T.sizeof, 0)
+   WriteVal(this.bytes, this.head, n)
+
+proc VtableEqual*(a: seq[uoffset]; objectStart: uoffset; b: seq[byte]): bool =
+   if a.len * voffset.sizeof != b.len:
+      return false
+
+   var i = 0
+   while i < a.len:
+      var seq = b[i * voffset.sizeof..<(i + 1) * voffset.sizeof]
+      let x = GetVal[voffset](addr seq)
+
+      if x == 0 and a[i] == 0:
+         inc i
+         continue
+
+      let y = objectStart.soffset - a[i].soffset
+      if x.soffset != y:
+         return false
+      inc i
+   return true
+
+proc WriteVtable*(this): uoffset =
+   this.PrependOffsetRelative(0.soffset)
+
+   let objectOffset = this.Offset
+   var existingVtable = uoffset 0
+
+   var i = this.current_vtable.len - 1
+   while i >= 0 and this.current_vtable[i] == 0: dec i
+
+   this.current_vtable = this.current_vtable[0..i]
+   for i in countdown(this.vtables.len - 1, 0):
+      let
+         vt2Offset: uoffset = this.vtables[i]
+         vt2Start: int = this.bytes.len - int vt2Offset
+
+      var seq = this.bytes[vt2Start..<this.bytes.len]
+      let
+         vt2Len = GetVal[voffset](addr seq)
+         metadata = 2 * voffset.sizeof # VtableMetadataFields * SizeVOffsetT
+         vt2End = vt2Start + vt2Len.int
+         vt2 = this.bytes[this.bytes.len - vt2Offset.int + metadata..<vt2End]
+
+      if VtableEqual(this.current_vtable, objectOffset, vt2):
+         existingVtable = vt2Offset
+         break
+
+   if existingVtable == 0:
+      for i in countdown(this.current_vtable.len - 1, 0):
+         var off: uoffset
+         if this.current_vtable[i] != 0:
+            off = objectOffset - this.current_vtable[i]
+
+         this.PrependOffsetRelative(off.voffset)
+
+      let objectSize = objectOffset - this.objectEnd
+      this.PrependOffsetRelative(objectSize.voffset)
+
+      let vBytes = (this.current_vtable.len + 2) * voffset.sizeof
+      this.PrependOffsetRelative(vBytes.voffset)
+
+      let objectStart: uoffset = (this.bytes.len.uoffset - objectOffset)
+      WriteVal(this.bytes, objectStart, (this.Offset - objectOffset).soffset)
+      this.vtables.add this.Offset
+   else:
+      let objectStart: uoffset = this.bytes.len.uoffset - objectOffset
+      this.head = objectStart
+      WriteVal(this.bytes, this.head,
+         (existingVtable.soffset - objectOffset.soffset))
+
+      this.current_vtable = @[]
+   result = objectOffset
+
+proc EndObject*(this): uoffset =
+   if not this.nested:
+      quit("builder is not nested")
+   result = this.WriteVtable()
+   this.nested = false
+
+proc End*(this: var Builder): uoffset =
+   result = this.EndObject()
+
+proc StartVector*(this; elemSize: int; numElems: uoffset;
+      alignment: int) =
+   if this.nested:
+      quit("builder is nested")
+   this.nested = true
+   this.vectorNumElems = numElems
+   this.Prep(sizeof(uint32), elemSize * numElems.int)
+   this.Prep(alignment, elemSize * numElems.int)
+
+proc EndVector*(this): uoffset =
+   if not this.nested:
+      quit("builder is not nested")
+   this.nested = false
+   this.Place(this.vectorNumElems)
+   this.vectorNumElems = 0
+   result = this.Offset
+
+proc getChars*(str: seq[byte]): string =
+   var bytes = str
+   result = GetVal[string](addr bytes)
+
+proc getBytes*(str: string | cstring): seq[byte] =
+   for chr in str:
+      result.add byte chr
+   result.add byte 0
+
+proc Create*[T](this; s: T): uoffset = # Both CreateString and CreateByteVector functionality
+   if this.nested:
+      quit("builder is nested")
+   this.nested = true
+   when T is cstring or T is string:
+      let x = s.getBytes()
+      let l = x.len.uoffset
+      this.vectorNumElems = l-1
+   else:
+      let x = s
+      let l = x.len.uoffset
+      this.vectorNumElems = l
+   this.Prep(uoffset.sizeof, l.int * byte.sizeof)
+   this.head -= l
+   this.bytes[this.head..<this.head+l] = x
+   result = this.EndVector()
+
+proc Finish*(this; rootTable: uoffset) =
+   if this.nested:
+      quit("builder is nested")
+   this.nested = true
+
+   this.Prep(this.minalign, uoffset.sizeof)
+   this.PrependOffsetRelative(rootTable)
+   this.finished = true
