DEV Community

krishnamoorthy k
krishnamoorthy k

Posted on

๐Ÿ“ Fixing BigInt Serialization Error in Node.js + Express (A Beginner-Friendly Explanation)

Hey everyone! ๐Ÿ‘‹
Iโ€™m a Node.js backend developer who worked mostly with MongoDB. Recently I shifted to SQL databases โ€” and the first unexpected challenge I faced wasโ€ฆ

๐Ÿ‘‰ BigInt. Yes, you heard that right.

SQL databases like MySQL/PostgreSQL often use BIGINT for primary keys and timestamps, especially when dealing with large IDs or auto-increment values.

Everything was fine until I fetched or created data and tried to return it through:

res.status(200).json(data);
Enter fullscreen mode Exit fullscreen mode

Boom. โŒ Node.js threw this error:

TypeError: Do not know how to serialize a BigInt

Enter fullscreen mode Exit fullscreen mode

This is where my debugging journey started.

โ— Why Does JSON Refuse BigInt?

Hereโ€™s the important part:
JSON does NOT support BigInt.

JSON only supports:

  • string
  • number
  • boolean
  • null
  • object
  • array

BigInt is not included. So when we do res.status(200).json({data:createdUser}) Express internally does: JSON.stringify(data)

โ€ฆit fails because:

JSON.stringify({ id: 123n });
Enter fullscreen mode Exit fullscreen mode

// โŒ Throws error

๐Ÿ” My First Solution (Manual Conversion)

Initially, I wrote a utility function that walked through my object and converted any BigInt to a string.

Something like:

function convertBigInt(obj) {
  // check object values and convert BigInt โ†’ string
}

Enter fullscreen mode Exit fullscreen mode

But this had 3 major problems:

  1. Needed to call it manually on every response
  2. Nested objects became difficult
  3. Extra processing on every endpoint

So I needed a better, global solution.

๐Ÿš€ The Cleanest Fix: Overriding BigInt Serialization Globally

Here is the solution that solved everything in one line:

const setupBigIntSerialization = () => {
  BigInt.prototype.toJSON = function () {
    return this.toString();
  };
};
Enter fullscreen mode Exit fullscreen mode

What does this do?
Whenever JSON.stringify() encounters a BigInt,
it calls .toJSON() if it exists.

So now:

JSON.stringify({ id: 123n });
Enter fullscreen mode Exit fullscreen mode

returns:

{ "id": "123" }

Enter fullscreen mode Exit fullscreen mode

โœ” No error
โœ” No precision loss
โœ” No need for manual conversion
โœ” Works for all Express responses

๐Ÿ“‚ How to Use This in Your Project

Step 1: Create a utility file

utils/bigintSerialization.js

const setupBigIntSerialization = () => {
  BigInt.prototype.toJSON = function () {
    return this.toString();
  };
};

export default setupBigIntSerialization;
Enter fullscreen mode Exit fullscreen mode

Step 2: Call this function in your entry file

In server.js or app.js:

import setupBigIntSerialization from "./utils/bigintSerialization.js";

setupBigIntSerialization(); // enable BigInt โ†’ string globally
Enter fullscreen mode Exit fullscreen mode

Step 3: Done.

Now every res.json()will safely serialize BigInt values without crashing your API.

โš ๏ธ Why Not Convert BigInt to Number?

Because itโ€™s unsafe.

If you do:

Number(123456789012345678901n);

Enter fullscreen mode Exit fullscreen mode

You will lose precision because JavaScript number uses double-precision floating point.

Thatโ€™s why the correct, safe approach is converting BigInt โ†’ string, not BigInt โ†’ number.

๐Ÿง  Bonus: Why This Works Internally

This is the part that helped me fully understand whatโ€™s going on.

Express uses JSON.stringify()

JSON.stringify() checks if the value has a .toJSON() method

If yes โ†’ it uses the return value of .toJSON()

So we override BigIntโ€™s default .toJSON()

Now BigInt becomes JSON-safe automatically everywhere

This is the same mechanism that JavaScript uses for:

Date

Map

Set

Custom classes

๐ŸŸข Final Result

After adding that one tiny helper, everything worked smoothly:

  • No more BigInt errors
  • No more manual conversions
  • Cleaner backend code
  • Safe for all routes and all responses

๐ŸŽ‰ Final Thoughts

If youโ€™re moving from MongoDB to SQL or using ORMs like Prisma, Sequelize, TypeORM, etc., you will eventually deal with BigInt values.

This small utility makes your entire API BigInt-proof with almost no effort.

I hope this post helps you the same way this fix helped me.
If you have any questions or want me to write a part-2 explaining JSON.stringify and serialization in depth โ€” comment below!

Happy coding! ๐Ÿš€

Top comments (0)