diff --git a/ts/byte-buffer.ts b/ts/byte-buffer.ts
index b936c7b..bb77f3b 100644
--- a/ts/byte-buffer.ts
+++ b/ts/byte-buffer.ts
@@ -1,8 +1,7 @@
-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";
+import { FILE_IDENTIFIER_LENGTH, SIZEOF_INT } from "./constants.js";
+import { int32, isLittleEndian, float32, float64 } from "./utils.js";
+import { Offset, Table, IGeneratedObject } from "./types.js";
+import { Encoding } from "./encoding.js";
 
 export class ByteBuffer {
     private position_ = 0;
@@ -75,12 +74,12 @@
       return this.readInt32(offset) >>> 0;
     }
   
-    readInt64(offset: number): Long {
-      return new Long(this.readInt32(offset), this.readInt32(offset + 4));
+    readInt64(offset: number): bigint {
+      return BigInt.asIntN(64, BigInt(this.readUint32(offset)) + (BigInt(this.readUint32(offset + 4)) << BigInt(32)));
     }
   
-    readUint64(offset: number): Long {
-      return new Long(this.readUint32(offset), this.readUint32(offset + 4));
+    readUint64(offset: number): bigint {
+      return BigInt.asUintN(64, BigInt(this.readUint32(offset)) + (BigInt(this.readUint32(offset + 4)) << BigInt(32)));
     }
   
     readFloat32(offset: number): number {
@@ -108,8 +107,8 @@
     }
   
     writeUint16(offset: number, value: number): void {
-        this.bytes_[offset] = value;
-        this.bytes_[offset + 1] = value >> 8;
+      this.bytes_[offset] = value;
+      this.bytes_[offset + 1] = value >> 8;
     }
   
     writeInt32(offset: number, value: number): void {
@@ -120,20 +119,20 @@
     }
   
     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;
+      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);
+    writeInt64(offset: number, value: bigint): void {
+      this.writeInt32(offset, Number(BigInt.asIntN(32, value)));
+      this.writeInt32(offset + 4, Number(BigInt.asIntN(32, value >> BigInt(32))));
     }
   
-    writeUint64(offset: number, value: Long): void {
-        this.writeUint32(offset, value.low);
-        this.writeUint32(offset + 4, value.high);
+    writeUint64(offset: number, value: bigint): void {
+      this.writeUint32(offset, Number(BigInt.asUintN(32, value)));
+      this.writeUint32(offset + 4, Number(BigInt.asUintN(32, value >> BigInt(32))));
     }
   
     writeFloat32(offset: number, value: number): void {
@@ -301,19 +300,12 @@
       }
       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[] = [];
+    createScalarList(listAccessor: (i: number) => unknown, listLength: number): any[] {
+      const ret: any[]  = [];
       for(let i = 0; i < listLength; ++i) {
         if(listAccessor(i) !== null) {
           ret.push(listAccessor(i));
@@ -324,28 +316,21 @@
     }
   
     /**
-     * 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[] = [];
+    createObjList(listAccessor: (i: number) => unknown, listLength: number): any[] {
+      const ret: any[] = [];
       for(let i = 0; i < listLength; ++i) {
         const val = listAccessor(i);
         if(val !== null) {
-          ret.push(val.unpack());
+          ret.push((val as IGeneratedObject).unpack());
         }
       }
       
       return ret;
     }
   
-  }
\ No newline at end of file
+  }
