Story of Building XCalc

Table Of Contents

  1. Why I built XCalc?
  2. How I built it
  3. Conclusion

#Why I built XCalc?

We all have a pre-installed calculator app on our devices (except iPad users). They provide us with basic and some advanced operations. For the majority of people, in most cases, that is more than enough.

However, as a maths student, I sometimes encounter problems that can easily be solved with a computer or calculator, but none of the calculator apps I have found include the necessary functionality. For instance, prime factorization is a fairly difficult task to do manually. But a computer could accomplish it in the order of seconds. I have never seen this functionality included in a calculator app, and this gap inspired me to develop XCalc, a calculator app with those extra functions.

Note that I only added the functions that are not available in those existing calculator apps. I intentionally left out the functions like log or sqrt, because they are already available in the pre-installed calculator apps.

So, what functions did I add? Here is a list. (You can find them on XCalc's Help page as well)

  • is-prime: checks if a number is a prime number
  • factors: finds all the factors of a number
  • lcm: finds the least common multiple of a list a numbers
  • gcd: finds the greatest common divisor of a list a numbers
  • factorial: finds the n-th factorial
  • ratio: finds the minimum ratio in a list of numbers
  • nck: finds the binomial coefficient denoted by (n k)
  • prime-factorize: finds the prime factorization of the given number

If you like the idea of XCalc, you can try it here. From the website, XCalc can be installed to your devices (I don’t know if it is supported on all operating systems and all browsers). And XCalc is available on Google Play Store as well.

If you are interested to see how XCalc is coded, Good news, XCalc's source code is available on GitHub.

#How I built it

Before you go on, you should note that this section is about the Web version of XCalc and not about the Android version (native).

#TypeScript

TypeScript is a strict syntactical superset of JavaScript and adds optional strict typing to the language. It compiles to JavaScript.

I decided to bring it into the code base mainly for two reasons. The primary reason is prevention of numerous tiny bugs. As TypeScript allows me to set types to everything, now I don’t have to worry as much about the code and be confident that I won't encounter runtime errors in most cases.
The second reason is, reduced mental overload. Which means, now, I don’t have to remember the function parameters and object structures. My IDE's intellisense takes care of that.

#UI Design

When starting with a new app, it's recommended to design the UI before starting the development. Here's a video from DesignCourse explaining why.

Hence, I decided to design (or at least try to) the whole UI first. I opened up Figma and gave it a shot. Here's what I designed.

XCalc Old UI design

Even though it's a dull design, I went with it. Because, the important thing about XCalc is its functionality; not the UI.

After getting XCalc to work basically, I stopped working on it for about 3 months. When I returned to the project, I decided to rewrite the whole app with better technologies. As a part of that, I redesigned the UI. It turned out to be pretty great.

XCalc New UI design

#React/Preact

When I first started developing XCalc, I didn't use any front-end libraries and instead I wanted to write all the code by myself. I wrote code to manage both the state of the app and the dynamic UI rendering, and it worked fine. But when I returned to the project after about the time gap, I found that I didn't understand any of the code I had initially written — it was a mess. That's when I realized that I should use a front-end library.

While rewriting the app, I chose to go with React, which is my favorite front-end library.

To be honest, the React code was not that good either. But it was a lot more readable than my initial code.

Recently, XCalc has started using Preact, instead of React. Preact is just like React but faster and lighter.

#Sass

Sass is a pre-compiler for CSS. It provides some additional functionalities which results in a better developer experience. That’s the one and only reason I decided to use Sass.

#Off-thread evaluations

By default, the browser uses a single thread ("main thread") to run all the processes of a website. This is where the layout and paint are done; the user events get processed; and the JavaScript runs. Which means, long-running JavaScript will block the thread, leading to an unresponsive page (== bad user experience)

This is where web workers come into play. Web workers are a simple means for web content to run scripts on background threads. This will make sure the main thread is free from getting stuck. Learn more about web workers on MDN.

XCalc never blocked the main thread (on my laptop and my phone), it worked without any problems. There were no performance issues at all. But, on the low-end phones, performance issues might rise.

And, it's a good idea to use the main thread only for UI work. That's why the main thread is called "UI thread" on other platforms. So, I moved the evaluations of the input to a web worker.

#Offline support

Service workers are a special type of web workers. A service worker is essentially a JavaScript file that runs separately from the main browser thread (or UI thread), intercepting network requests, caching or retrieving resources from the cache, and delivering push messages.
Google Developers Blog(@)

With the use of service workers, web apps can now deliver a custom offline experience. For example, YouTube and Spotify have a custom offline page. While searching for more examples, I found this awesome sudoku game, which is completely available for offline use.

Like that sudoku game, XCalc doesn’t need an active internet connection to work. So, as you may guess, I wanted to make XCalc completely offline, just like that game. So, I added a service worker to do that. It pre-caches all the required resources. After that, the resources will be loaded from the cache.

#WebAssembly (AssemblyScript)

WebAssembly (WASM, in short) is a new type of code that can be run inside web browsers. It is a low-level assembly-like language which runs with near-native performance. But, keep in mind that WASM is not intended to replace JS, and it won’t.

I recently became aware of WebAssembly, which was first introduced in 2017, and decided to use it in XCalc. Although WebAssembly wasn't meant to be used in a calculator app like XCalc, I chose to use it for learning and experimentation.

C, C++, Rust can be compiled to WASM. But I didn't know any of them (I still don't). And I didn't want to learn them. Fortunately, I came to know about AssemblyScript. AssemblyScript is a typescript-based language which compiles to WASM. With the familiar syntax, AssemblyScript appeared to be the best option for me. So, I chose to use it.

Getting started with AssemblyScript was a little hard for me. But, maybe, that was mostly because I didn't read the documentation clearly.

#Conclusion

Overall, working on XCalc was a really great experience for me. There was a lot of fun and learning.

Here is the main thing I learnt while building XCalc.

Read the documentation clearly. One of my bad habits is not reading documentation thoroughly. I always miss something in every documentation I read, which has caused me to spend a significant amount of time trying to figure out how to do something that was already explained in the documentation. When reading documentation for something, it is important to read it thoroughly and not skip anything. When you encounter a bug or an error, make sure your have checked the official documentation, before searching for solutions in other places.

If you have read this much, Thank you for your time. Have any questions? Feel free to reach me out on Twitter