Details Link to this heading

  • Live Demo
  • Source Code
  • Tech Stack: HTML/SCSS, JavaScript, Webpack, Netlify
  • Project Type: Personal
  • Year(s) Built: 2022-23

Why did I build Free Fitness Tools? Link to this heading

I’ve been using basic JS in my projects to add interactivity on the frontend for quite some time now. However, my projects are typically backend-focused and I haven’t had a chance to build many pure frontends. That’s why I decided to take this on as a learning experience. I hope to continue improving my JS skills until I’m comfortable building out complex frontends, at which point I’ll experiment more with frameworks.

Technologies Used Link to this heading

The bulk of the app is built with HTML, SCSS and Vanilla JavaScript and no 3rd-party dependencies (except for dev tools). Webpack and html-webpack-plugin are used for module bundling, SCSS compilation, and basic template generation. The app is deployed to Netlify which monitors updates to the master branch and re-builds/re-deploys the site accordingly.

SPA, SSG, or Templating? Link to this heading

While I could’ve used a Single-Page App (SPA) architecture for this project, for SEO purposes I decided to create separate routes for each tool. Using a templating language or static site generator (SSG) for this would’ve made my life a lot easier and deduplicated a lot of HTML markup. However, I wanted to give a pure Webpack approach a shot to see how that works.

What I did was use html-webpack-plugin to build the templates to an index.html file in a tool-specific subdirectory, e.g. /max-lifts/index.html. This can be done with an HtmlWebpackPlugin instance like so:

1new HtmlWebpackPlugin({
2  title: 'Max Lift Calculator',
3  filename: 'max-lifts/index.html',
4  template: 'src/html/max-lifts.html',

Then I created catch-all redirects in Netlify to redirect any direct traffic to the index.html file to its respective path, e.g. /max-lifts/. Even without the redirects, requests to /max-lifts/ would serve up the content of the index.html in that directory. So this isn’t 100% necessary if you use rel="canonical" tags but I couldn’t find an easy way to inject custom, page-specific <link> tags with html-webpack-plugin. The redirects are simply a temporary workaround for this to ensure that duplicate content doesn’t confuse search engines.

Avoiding Global Variable Scope Link to this heading

Throughout the project, I had a handful of DOM elements that I had to access across multiple function scopes, and adding these to the global namespace of a module seemed like bad practice.

After some research, I decided to use a global static namespace object as the entrypoint to each tool’s module, where I could keep track of the calculation results, handle form submission, and more.

I’m still not sure if this is best practice for larger applications, but it seemed to work just fine for my use case and feels much better than storing everything globally (name clashes, etc.).

Included Fitness Tools Link to this heading

The initial release of the app includes two useful tools for fitness enthusiasts: a max lifts (one-rep max) calculator and a calorie target (BMR/TDEE) calculator.

Max Lifts Calculator Link to this heading

There are a handful of popular formulae for calculating one-rep max. Many of the existing tools online obfuscate the formula used to perform those calculations. This tool in particular strives to bridge that gap by giving the user a choice between averaging the results of all the formulae or selecting a specific formula to run the calculations against.

The result of the 1RM calculation is then used to reverse engineer the amount of reps one is expected to perform at a percentage of that 1RM. To do so, the formulae are rearranged to solve for reps using the 1RM and weight at a % of the 1RM (the standard formula uses the user-inputted weight and reps to solve for 1RM).

During this process, I discovered flaws in a handful of the formulae that make them less than ideal for predicting rep volume at a % of 1RM at higher rep ranges.

Calorie Target Calculator Link to this heading

The second tool uses biometrics to estimate the amount of calories one should expect to consume in order to gain, lose or maintain weight based on their fitness goals.

First, BMR is calculated based on height, weight, age and gender which is the amount of energy your body consumes at rest. Maintenance calories (TDEE) are then derived from estimated activity level using standard multipliers. Lastly, a calorie modifier determines the amount of calories that should be consumed based on a user’s personal weight goals.

To tie it all together, an output table visualizes the calorie targets for various activity levels and weight goals, and highlights the user’s desired result for easy review.

Future tools Link to this heading

I do plan to add more tools in the future once I find time to revisit the project. Some ideas I have are a relative intensity calculator for weightlifting and a macro ratio calculator to compliment the calorie targets one.


See Also

Read Next