Onuorah Bonaventure Full-stack web developer that loves connecting brands to their customers by developing amazing, performant websites. Interested in teaching programming concepts and breaking down difficult concepts. When I'm not coding, I play chess and checkers with my friends while listening to cool Afrobeats.

How to use JavaScript’s BigInt

14 min read 4179 111

How to Use JavaScript's BigInt

Before the release of ES2020, there was no native way to use JavaScript to accurately represent and perform mathematical operations on numbers greater than 9,007,199,254,740,991 or 253 – 1, or less than -9,007,199,254,740,991 or -(253 – 1). Most developers relied on libraries such as JSBI and bignumber.js to perform calculations on large numbers.

Fortunately, this situation gave rise to a data type called BigInt. The introduction of BigInt brought the total number of JavaScript data types to eight. In this article, we will learn what BigInt is, its advantages, and how to use it in JavaScript properly. To learn more about representing large numbers in your Node.js applications, check out our guide here.

Jump ahead:

What is BigInt?

BigInt is a numerical data type that can be used to represent both small and large numbers that cannot be represented by the older numerical data type, number. Every BigInt value must contain a lowercase n after the number, e.g., 897n. Therefore, it is accurate to state that 21 is not strictly equal to 21n because the former is a number while the latter is a bigint.

When you perform a mathematical operation on any number greater than 9,007,199,254,740,991 or Number.MAX_SAFE_INTEGER, you do not really get an accurate answer. We can see the demonstration below:

See the Pen
Bigint inllustrations and examples
by Onuorah Bonaventure Chukwudi (@bonarhyme)
on CodePen.

However, we can use BigInt to handle these kinds of operations accurately. To define an integer as BigInt, we do either of the following methods:

  1. We could append n to a whole number, or
  2. Call the BigInt() constructor on whole numerical values or strings with only integer values

They are demonstrated in the example below:

// Method 1
const sampleBigIntOne = 234n;

// Method 2
const sampleBigIntTwo = BigInt(567)
// This returns 567n

const sampleBigIntThree = BigInt("123")
// This return 123n

const sampleBigIntFour = 12356789900099999999912111n
// Still correct

To verify that a value is of the type BigInt, we can use the typeof operator, like this:

const sampleOne = 17n
console.log(typeof sampleOne)
// Expected result: "bigint" 

const sampleTwo = BigInt(789);
console.log(typeof sampleTwo)
// Expected result: "bigint"
// This is a bad practise

const sampleThree = typeof 17n === "bigint"
// Expected result: true

N.B., passing numbers inside the BigInt constructor is a bad practice. Instead, it is better to just append n or to first wrap it in a string, as in sampleBigIntOne and sampleBigIntThree.

Practical use cases for BigInt

BigInt values find their use in applications that handle large numbers. Here are some key use cases of BigInt:

  • Financial calculations: BigInt is important in financial calculations because of the possibility of handling very large amounts of transactions and currency conversions
  • Cryptography and security computing: BigInts are used in cryptography to generate really large random numbers that are very difficult to predict or crack
  • Game developments: In game developments, large numbers are usually used to hold timestamps, points, and to track progress. The use of BigInt ensures the accurate representation of such values
  • Distributed systems: Distributed systems require unique identities to perform accurately. Since BigInt values are unlimited, they can be used to generate identifiers and keys

BigInt is really important in these fields because it allows developers to safely and precisely handle huge integers, timestamps, IDs, and progress.

BigInt vs. Number

Generally, a number in JavaScript can be used to represent an integer and even a float, such as 69 and 4.125677 respectively. It includes values that range between 9,007,199,254,740,991 or 253 – 1 and -9,007,199,254,740,991 or -(253 – 1). These limits are available as constants, such as Number.MAX_SAFE_INTEGER and Number.MIN_SAFE_INTEGER, respectively.

As a matter of fact, you can perform all arithmetic operations, such as addition (+), subtraction (-), multiplication (*), division (/), remainder or modulo (%), and exponent (**) on numbers in that range without any problems, but that isn’t totally the case with bigint.

Bigint can be used to represent and perform operations on any size of integer except floats or decimals including numbers greater than 9,007,199,254,740,991 or less than -9,007,199,254,740,991. This means that decimal values such as 17.2n are invalid.

Generally, all the arithmetic operations except (/) will give a correct mathematical answer when used between two or more bigint values. For instance, the division operator doesn’t give an accurate result at all times. This means that operations such as 5n/2n will round off to 2n instead of 2.5n.

Limitations of the Number type

The JavaScript number type is written as double-precision 64-bit binary format IEEE 754 value, meaning that 52 bits are used for significant values while one bit and 11 bits are used for the sign and exponents. Therefore, we’ll likely face some limitations whenever we use number. These limitations include:

  • Round-off errors and Limited precision of numbers
  • Inability to perform precise operations outside the minimum and maximum safe integers
  • Failure to perform operations outside a MAX_VALUE and MIN_VALUE range

JavaScript is bound to round off numbers because it uses 64 bits to represent a floating number. This means that every number in JavaScript is first converted to a double-precision binary floating-point number before it is stored in the memory. In fact, the 64-bit representation of a number is actually divided into three parts, including the significand, biased exponent, and the sign.

For example, a number such as 15 looks like this after it is converted: 0.10000000010.1110000000000000000000000000000000000000000000000000

N.B., you can go here to convert some numbers to a double-precision binary floating-point number

The first part of a double-precision binary floating point is the sign, which can be 0 or 1, standing for a positive and negative sign of the number. So, it is positive when the sign is 0, and vice versa. It takes up 1 bit. The second part is the biased exponent, which takes up 11 bits, while the last part is the significand or mantissa, which takes up 52 bits.

Some numbers give an exact value, such as 1/2, 1/4, 1/5, 1/8, 1/10, and every whole number in the range of 9,007,199,254,740,991 or 253 – 1 to -9,007,199,254,740,991 or -(253 – 1). Some other numbers do not give exact values; instead, they are repeating decimals, such as 1/3, 1/6, 1/7, 1/9.

The problem lies in the fact that some of these decimal numbers lose precision when they are converted to binary and vice versa. So, when you take a decimal number, such as 0.1, and add it up to 0.2, they do not add up to 0.3. Instead, they add up to 0.30000000000000004. More examples can be seen below:

const sample1 = 0.2 + 0.6
// This returns 0.6000000000000001 instead of 0.6

const sample2 = 0.3 + 0.6
// This returns 0.8999999999999999 instead of 0.9

This is a huge problem when using numbers because it can pose a great risk in calculations that require high precision. This problem would be avoided when we use bigint it because it doesn’t accept decimals.

JavaScript numbers can only be precise when you perform an arithmetic operation between 9,007,199,254,740,991 or 253 – 1 to -9,007,199,254,740,991, or -(253 – 1). This means that whatever operation you perform outside that range can result in a wrong answer, such as:

const sample3 =  9_007_199_254_740_991 + 1
// This gives  9,007,199,254,740,992

const sample4 = 9_007_199_254_740_991 + 2
// This gives 9,007,199,254,740,992

// However:
console.log(sample3 === sample4)
// Given result: true
// Expected result: false

JavaScript also has a limit for the amount of numbers it can represent. In fact, the numbers are important, and they can be represented with two built-in constants: Number.MAX_VALUE and Number.MIN_VALUE. They are essentially the numbers: 1.7976931348623157e+308 and 5e-324 respectively.

Whenever you try to perform an addition or subtraction with Number.MAX_VALUE, it returns 1.7976931348623157e+308 without adding or subtracting any value. And when you try to do the same with Number.MIN_VALUE, it returns the value as in the samples below:

const sample5 = Number.MAX_VALUE + 7
// Returns 1.7976931348623157e+308

const sample6 = Number.MAX_VALUE - 23
// Returns 1.7976931348623157e+308

const sample7 = Number.MIN_VALUE + 5
// Returns 5

const sample8 = Number.MIN_VALUE - 54
// Returns -54

It gets crazier when you perform a multiplication (*) or exponent (**) on Number.MAX_VALUE as it always returns Infinity. This value is represented as Number.POSITIVE_INFINITY.

As you can see, only division works for Number.MAX_VALUE and only multiplication works for Number.MIN_VALUE. This is a serious limitation when you are required to perform calculations involving very high numbers. However, with the help of BigInt, we can perform calculations on very high or low numbers.

Advantages of using BigInt

Now, let’s dive into the advantages of using BigInt in JavaScript. First, BigInt ensures that we do not encounter round-off errors. When we work with numbers, we are allowed to use decimals which can lead to precision and round-off errors as we have seen in the previous section.

However, we aren’t allowed to work with decimals when we use BigInt. This ensures that such errors are avoided at all times. Therefore, it is invalid to do the following:

const sample1 = 5.4n;
// This will throw a SyntaxError

BigInts also makes it possible to perform calculations with arbitrary precision. Unlike numbers that lose precision when we perform calculations outside the range of Number.MAX_SAFE_INTEGER and Number.MIN_SAFE_INTEGER, BigInt allows us to perform such calculations without losing any precision. It can be shown in the example below:

var sample2 = BigInt(Number.MAX_SAFE_INTEGER) + 1n
var sample3 = BigInt(Number.MAX_SAFE_INTEGER) + 2n

// Expected result: 9007199254740992n

// Expected result: 9007199254740993n

// Therefore:
console.log(sample3 > sample2)
// Expected result: true

Interestingly, with BigInt, we can safely and precisely perform calculations on integers that are bigger than Number.MAX_VALUE because it has an arbitrary precision, meaning that the size of the integer it can perform operations on is only limited by the available memory on the host computer or system. This means that we cannot encounter the same problems when working with BigInt:

const max = BigInt(Number.MAX_VALUE)
// Expected Result: 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368n

const sample4 = max + 7
// Expected Result: 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858375n

const sample5 = max - 23
// Expected Result: 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858345n

Additionally, BigInt allows us to set a boundary on the number of bits we want to permit for a calculation. This means we can define the appropriate range of integers we want for our program. We can achieve this using the asIntN and asUintN methods that are available on the BigInt prototype.

Essentially, the two methods are used to wrap a BigInt value to a width-digit binary signed and unsigned integer, respectively. It is worth noting that signed integers are used to represent negative values and vice versa.

Hence, if we want to limit our calculations to 8-bit, 16-bit, 32-bit, or 64-bit arithmetic, we can use the asIntN method to achieve that by calling it completely with BigInt.asIntN(width, value). In this case, the width parameter represents the desired bits that are greater than zero, whereas the value parameter represents the BigInt value we want to limit within the supplied width.

Let’s look at an example:

const maximumBits = 16;

const valueOne = BigInt(32767);
const constrainedValueOne = BigInt.asIntN(maximumBits, valueOne);
// Expected result: 32767n

const valueTwo = BigInt(32768);
const constrainedValueTwo = BigInt.asIntN(maximumBits, valueTwo);
// Expected result: -32768n

As you can see in the example above, we created a 16-bit limit of integers we want to work with by using the asIntN. Generally, 16-bits can only contain integers between -32768n and 32767n. Hence, in the first example, it returned the value as is, whereas, in the latter, it truncated the value because it was outside the range we have specified.

More great articles from LogRocket:

BigInt also improves speed in JavaScript applications. Before ES2020, developers relied on libraries such as Math.js and JSBI to calculate large numbers. However, some of these packages were heavy and slow. This caused applications and software built with JavaScript to perform slowly; however, the addition of BigInt which is a native solution will allow the improvement of applications that perform calculations with large numbers.

And lastly, BigInt can form a basis for the development of BigDecimal. One core feature of BigInt is that it doesn’t permit the use of floats. However, floats come in handy in some aspects of development. Hence, the JavaScript specifications builders could take a hint and implement a native data type that could be used to represent floats that are precise and probably help us perform more accurate calculations, such as 0.1 + 0.2 = 0.3.

How to use BigInt in JavaScript

Because BigInt is a data type it is similar to numbers and can also be used to perform calculations. To define a BigInt value, we can use BigInt literal, which is n, or use the BigInt constructor on a string containing integers or on numbers.

However, we should be wary about coercing numbers to BigInt using the constructor because numbers might lose precision even before the conversion occurs. Here’s what that looks like:

const dontDoThis = BigInt(12345567891234567890)
// Given result: 12345567891234568192n
// Expected result: 12345567891234567890n

const dontDoThisToo = BigInt(`${12345567891234567890}`)
// Given result: 12345567891234568000n
// Expected result: 12345567891234567890n

As you can see in the examples above, we lost precision when we coerced a number to BigInt. Therefore, we are advised not to do that, and should do this instead:

const doThis = BigInt("12345567891234567890")
// Expected result: 12345567891234567890n

const doThisAlso = 12345567891234567890n
// Expected result: 12345567891234567890n

const numberInString = "12345567891234567890";
const doThisToo = BigInt(numberInString)
// Expected result: 12345567891234567890n

Working with BigInt methods

There are five different methods you can use with a call on the BigInt class:

  • BigInt.prototype.toString()
  • BigInt.prototype.valueOf()
  • BigInt.prototype.toLocaleString()
  • BigInt.asIntN()
  • BigInt.asUintN()

Whenever you encounter a method like BigInt.prototype.toString(), it means the method toString() will be called on a BigInt integer like 5n.toString(), whereas methods such as BigInt.asUintN() will be called directly on the BigInt constructor like this BigInt.asIntN(maximumBits, valueTwo)


First, let’s look at BigInt.prototype.toString(). The toString() is used to convert a BigInt value to a string. It essentially wraps the BigInt with a double or single quote while removing the trailing n. It can be used like this:

const value1 = 35n;
const sample1 = value1.toString()

// Expected result: "35"

You can verify that the returned value is now a string by using the typeof as shown below:

const value1 = 35n;
const sample1 = value1.toString()
const valueDataType = typeof sample1

// Expected result: string

Optionally, you can also pass a radix when converting a BigInt to string. A radix is actually the base you want to convert to. The radix to be passed ranges from 2 to 36. Also, when no radix is passed, it defaults to base 10. Hence, you can pass a radix like this:

const value = 10n;

const newValueBase16 = value.toString(16)
// Expected result: "a"

const newValueBase5 = value.toString(5)
// Expected result: "20"

const newValueBase10 = value.toString(10)
// Expected result: "10"


The valueOf method is used to get the primitive type of a BigInt object. It demonstrated in the examples below:

const value = Object(7n)

const valueOfDataType1 = typeof Object(7n)
// Expected result: object

// You can use the .valueOf method to get the primitive type
const valueOfDataType2 = typeof Object(7n)
// Expected result: bigint


The toLocaleString() method works similarly to the toString() however, it can be used to return the string in a language-specific way or format. It accepts two parameters which are the locale and the options. It can be used like this:

const value = 23345689n;

const valueAsFormattedString = value.toLocaleString('en-US')
// Expected result: 23,345,689

const valueAsFormattedStringWithOptions = value.toLocaleString('en-US', { style: 'currency', currency: 'USD' })
// Expected result: $23,345,689.00


The BigInt.asIntN() is used to limit a BigInt value within a set bit-width while retaining the sign of the value. The syntax is as follows: BigInt.asIntN(bitWidth, BigIntValue). Therefore, it is suitable when we want to preserve the sign of a BigInt value even when we want to constrain it.

Generally, the bitWidth can be 8-bits, 16-bits, 32-bits, etc. So, when we set the width to be 8-bits, we are essentially saying that we want to accept a total of 256 BigInt values that range between -128 to 128.

Note that it returns the value as it is if the value falls within the range of the accommodated values by the bit and it returns the equivalent of the value in the bit if it exceeds the range. It demonstrated in the examples below:

const bits = 8;
const value1 = 126n; // Still in the range of -128 to 128
const value2 = 127n; // Still in the range of -128 to 128
const value3 = 128n; // Not in the range of -128 to 128
const value4 = 129n; // Not in the range of -128 to 128
const value5 = -67n; // Still the range of -128 to 128

const result1 = BigInt.asIntN(bits, value1)
// Expected result: 126n

const result2 = BigInt.asIntN(bits, value2)
// Expected result: 127n

const result3 = BigInt.asIntN(bits, value3)
// Expected result: -128n
// -128n is the equivalent

const result4 = BigInt.asIntN(bits, value4)
// Expected result: -127n
// -127n is the equivalent

const result5 = BigInt.asIntN(bits, value5)
// Expected result: -67n


BigInt.asUintN() performs similarly to BigInt.asIntN(). The major difference is that it disregards the sign on the BigInt value to be constrained, which only constrains between zero and the maximum quantity the bit can contain. For instance, 8-bits can contain 256 values; therefore, it will constrain between 0 to 256 with 0 inclusive. It is demonstrated in the sample below:

const bits = 8;
const value1 = 254n; // Still in the range of 0 to 256
const value2 = 255n; // Still in the range of 0 to 256
const value3 = 256n; // Not in the range of 0 to 256
const value4 = 257n; // Not in the range of 0 to 256
const value5 = 258n; // Not the range of 0 to 256

const result1 = BigInt.asUintN(bits, value1)
// Expected result: 254n

const result2 = BigInt.asUintN(bits, value2)
// Expected result: 255n

const result3 = BigInt.asUintN(bits, value3)
// Expected result: 0n
// 0n is the equivalent

const result4 = BigInt.asUintN(bits, value4)
// Expected result: 1n
// 1n is the equivalent

const result5 = BigInt.asUintN(bits, value5)
// Expected result: 2n
// 2n is the equivalent

To determine the range of numbers a bit can contain, we can use this formula for signed integers when using BigInt.asIntN() :

// For signed values - BigInt.asIntN()

let bitWidth = n;
let minimumRangeValue = -(2^(n-1)); // negative two to the power of n  minus 1
let maximumRangeValue = (2^(n-1)) - 1; // two to the of n minus 1, minus 1
//let  range = minimumRangeValue - maximumRangeValue 
// from -(2^(n-1)) to (2^(n-1)) - 1

// Therefore if
n = 16; // 16 bits
minimumRangeValue = -(2^(16-1)) = -(2^15) = -32768;
maximumRangeValue = (2^(16-1)) - 1 = (2^15) - 1 = 32768 - 1 = 32767
// Range becomes -32768 to 32767 for signed 16 bits

Also, to determine the range of numbers a bit can contain, we can use this formula for unsigned integers when using BigInt.asUintN():

// For unsigned values - BigInt.asUintN()

let bitWidth = n;
let minimumRangeValue = 0;
let maximumRangeValue = (2^n) - 1; // two the power of n, minus 1
//let  range = minimumRangeValue - maximumRangeValue // 0 to (2^n) - 1

// Therefore if
n = 16; // 16 bits
minimumRangeValue = 0;
maximumRangeValue = (2^16) - 1 = 65536 - 1 = 65535;
// Range becomes 0 to 65535 for unsigned 16 bits

BigInt conditionals

Essentially, the conditions that work with numbers will also work with BigInt. This means that ||, &&, and ! will also work normally with BigInt. Also, when we use if statements, only the value 0n will evaluate to false while the other whole positive:

  console.log('It is in if')
  console.log("it is in else")
// Expected Result: it is in else

  console.log("it is in if")
  console.log("it is in else")
// Expected result: it is in if

   console.log("it is in if")
  console.log("it is in else")
// Expected result: it is in if

It’s worth saying that even the Boolean function will also work as expected. This means that only 0n will evaluate to false, as shown below:

const isValueNone = Boolean(0n)
// Expected result: false

const isValueExists1 = Boolean(79n)
// Expected result: true

const isValueExists2 = Boolean(-65n)
// Expected result: true

BigInt common rules and precautions

To use BigInt without seeing errors, there are rules we need to follow. Here’s the full list:

  • Do not use new keyword when creating BigInt
  • Do not use decimals with Bigint
  • Errors with BigInt coercion
  • Do not use JSON.stringify directly with BigInt
  • Do not use the positive unary operation with BigInt
  • Limited built-in methods
  • Division operations with BigInt returns a truncated result

First, do not use new keyword when creating BigInt. In JavaScript, we often use the new keyword to initialize a prototype of a class. However, that is not the case with BigInt as it will throw a TypeError when we use the new keyword:

// Do not do this -
const value = new BigInt(54);
// Expected result: Throws TypeError

Also, do not use decimals with Bigint. When we try to convert a decimal number to a BigInt value, it will throw a RangeError. Similarly, we will get a SyntaxError when using an implicitly converted BigInt with a decimal point:

// Do not do this:
const value = 7.8n + 9n;
// Expected result: Throws a SyntaxError

Additionally, you may run into errors with BigInt coercion, such as mixing numbers with BigInt will throw a TypeError:

// Do not do this:
const result = 2n + 4;
// Expected result: TypeError:  cannot convert BigInt to number

And, using null, undefined, and Symbol with BigInt will throw an error:

// Expected result: TypeError: can't convert null to BigInt

// Expected result: TypeError: can't convert undefined to BigInt

// Expected result: TypeError: can't convert Symbol() to BigInt

To avoid more errors, do not use JSON.stringify directly with BigInt. We cannot directly use the JSON.stringify direct on BigInt will throw a TypeError:

const theStringified = JSON.stringify(5n)
// Expected result: TypeError: BigInt value can't be serialized in JSON

Instead, we can stringify our BigInt value to implement out toJSON method or by using a replacer. To implement the toJSON method, we simply need to add the following piece of code to our program file before using the JSON.stringify() method:

BigInt.prototype.toJSON = function () {
  return this.toString();

To implement JSON.stringify() method using the replacer method, we simply have to add the following piece of code to our program:

const replacer = (key, value) => {
 return typeof value === "bigint" ? value.toString() : value

We can implement JSON.stringify() using any of the two methods like this:

// Method 1 -
// Implementing toJSON

// Add this before you inplement JSON.stringify()
BigInt.prototype.toJSON = function () {
  return this.toString();

const value1 = {one: 5n, two: 667n};
const value1ToJson = JSON.stringify(value1);
// Expected result: {"one":"5","two":"667"}

// Method 2 -
// Implement with a replacer
const replacer = (key, value) => {
 return typeof value === "bigint" ? value.toString() : value

const value2 = {seven: 7n, twenty: 20n, five: 5n};
const value2ToJson = JSON.stringify(value2, replacer)
// Expected result: {"seven":"7","twenty":"20","five":"5"}

Normally, the negative unary operation will always work with BigInt values. However, the positive will break the asm.js, which expects +value to always return a positive number or throw an error. So, don’t use the positive unary operation with BigInt because doing something like this +2n will throw a TypeError:

// Expected result: TypeError: can't convert BigInt to number

Limitations of BigInt

One of the limitations of BigInt is that we cannot use built-in Math functions in JavaScript. Instead, we are expected to construct our mathematic functions ourselves. Hence, performing operations such as Math.sqrt() will throw a TypeError exception:

// Expected result: TypeError: can't convert BigInt to number

Additionally, division operations with BigInt returns a truncated result. It has been established that BigInt values cannot be a decimal. This fact is extended to the division operation, which can sometimes return a decimal dividend, such as in 7 / 4 = 1.75. Hence, because of this, BigInt values will always be rounded to 0. That means that 7n / 4n = 1n and not 1.75n, as expected.

Browser and Node.js support

Any version of Node.js from v10.4, including newer versions such as v18.16, has support for BigInt. This means that the older version will throw a SyntaxError. Similarly, most modern browsers support BigInt. You can see the total supported browsers on caniuse.

At the time of writing, more than 94 percent of browsers support the BigInt constructor and its methods.



In this article, we learned about BigInts, their available methods, use cases, and the challenges of working with them. However, we should know that numbers are also great for day-to-day programs such as small websites and that we should use BigInts only when we are sure we will be working with large sums.

Thanks for reading. I hope you enjoyed this article, and be sure to leave a comment if you have any questions. Happy coding!

LogRocket: Debug JavaScript errors more easily by understanding the context

Debugging code is always a tedious task. But the more you understand your errors the easier it is to fix them.

LogRocket allows you to understand these errors in new and unique ways. Our frontend monitoring solution tracks user engagement with your JavaScript frontends to give you the ability to find out exactly what the user did that led to an error.

LogRocket Dashboard Free Trial Banner

LogRocket records console logs, page load times, stacktraces, slow network requests/responses with headers + bodies, browser metadata, and custom logs. Understanding the impact of your JavaScript code will never be easier!

Try it for free.
Onuorah Bonaventure Full-stack web developer that loves connecting brands to their customers by developing amazing, performant websites. Interested in teaching programming concepts and breaking down difficult concepts. When I'm not coding, I play chess and checkers with my friends while listening to cool Afrobeats.

Leave a Reply