Windy — Turn any HTML to Tailwind CSS! Learn more

Go back to Blog

Tracking privacy-first usage statistics in Electron apps with Fathom Analytics

Marcel Pociot

Our desktop applications started as little tools born out of the necessity of being useful for ourselves. Over time, those apps were no longer being used by ourselves only but by thousands of developers all over the world – Tinkerwell has more than 7,000 users on its own.

Up to this point we do not have any kind of analytics or statistics within any of our applications. We don't like to "track" the user behavior - especially not without their explicit consent.

When we started to work on the roadmap for a version 3.0 of Tinkerwell, we started thinking about features that we could remove - mostly because we personally don't use them.

The problem is that if thousands of developers use our software, we also need to get some insights into the application and learn how others are using our applications. Maybe that one feature that we personally do not use, is super important to hundreds or thousands of developers per day.

Because of this, we decided to add the ability to track anonymous usage statistics withink Tinkerwell – of course only after giving your consent. So if you want to keep the features that you use on a daily basis, please opt-in 😉

Due to our knowledge we gained by working on other mobile and desktop applications in the past, we know that Google has some kind of analytics tool that is specialized on this. But for various reasons, we did not want to use a Google Service. They are collecting way too much data, and we wanted something that has privacy as its core feature as well as a lightweight possibility to implement.

Tracking options

The first idea that we had was to build a custom analytics tracking solution ourselves. We could completely customize and specify which data we want to keep and want to collect – but this would also mean that we would need to create an API for this, build models, migrations, controllers, etc. And we haven't even started talking about how we might want to inspect that data for reporting purposes.

So instead of building this solution manually, we decided to use Fathom Analytics – a privacy focused analytics solution.

Dynamically enabling Fathom in your apps

As mentioned before, the data collection only happens after the user has given us the consent to do so. In order to dynamically activate or deactivate tracking inside of our Electron apps, we dynamically inject or remove the Fathom Analytics script tag into our apps. For this purpose, we created a Fathom JavaScript class that we can reuse across all of our apps:

class Fathom {

  constructor(url, site) {
    this.url = url;
    this.site = site;
  }

  inject() {
  	if (document.getElementById('fathom') !== null) {
  		return;
  	}

    let script = document.createElement("script");

    script.setAttribute("id", "fathom");
    script.setAttribute("src", url);
    script.setAttribute("data-site", this.site);

    document.head.appendChild(script);
  }

  remove() {
    try {
      document.getElementById('fathom').remove();
    } catch (err) {
      //
    }
  }

}

So in order to start using Fathom, here's what you can do:

// Create a new Fathom instance:
let analytics = new Fathom('https://my-site.usefathom.com/script.js', 'EXXFCKLA');
// Inject the analytics script tag into our site
analytics.inject();

Tracking Usage Statistics

So lets say we want to track whenever someone runs code within the testing mode in Tinkerwell. Of course, we don't want to track and send any code or evaluation results. The goal is to have a simple counter that tells us how many times people use a particular mode.

Fathom allows the creation of custom events, which we can track from within a website or app – but we need to create all these events beforehand and this is something that we don't want to do.

The current version of Fathom does not accept custom event parameters and we can't create an event which is called "Run Code" and then pass parameters, like the mode, to the event.

But Fathom allows you to manually track a page visit for a specified URL - and that's what we use to track the actual code run statistics. To make this work, we added a method called trackPageview to my Fathom class:

trackPageview(url) {
	try {
	  fathom.trackPageview({
	    url: `/${url}`,
	    referrer: `https://os/${process.platform}`
	  });
	} catch (err) {
	  //
	}
}

This method retrieves a "url" to track and sends it to Fathom Analytics. In addition to the URL, we use the operating system of the user and send it as a referrer. This string is not trackable in any way and only contains rather generic values, such as win32, linux or darwin. All of this is wrapped in a try-catch block in case that anonymous usage statistics are not enabled by the user.

In order to actually track a code run, this is the code being used:

runCode(activeTab) {
  let identifier = `run-code-${activeTab.tinkerMode}`;

  if (activeTab.connected) {
    identifier += "-ssh";
  }
  
  if (activeTab.useDocker) {
    identifier += "-docker";
  }

  if (activeTab.useVapor) {
    identifier += "-vapor";
  }

  this.trackPageview(identifier);
}

We build a "URL", that consists of a string that lets us know the mode that Tinkerwell runs in, as well as the information if the code is running via SSH, Docker or Vapor. So at the end, we might track a visit to a URL like:

run-code-cli run-code-testing-docker run-code-cli-vapor run-code-table-ssh

etc.

And that's all the information that we get!

Tracking free users

Starting with the latest version of Tinkerwell, we offer a free version, that allows you to run code up to 5 times a day. We'd like to track when a new free user starts using the application, as well as how often someone uses the daily limit. We are using the aforementioned events in Fathom Analytics.

startTrial() {
  this.trackGoal("GOAL-CODE");
}

trialExpired() {
  this.trackGoal("GOAL-CODE");
}

trackGoal(code) {
  try {
    window.fathom.trackGoal(code, 0);
  } catch (err) {
    //
  }
}

We hope this blog post gives you a good understanding of Fathom Analytics and how to add anonymous usage statistic tracking to your own applications and makes you confident to enable them in our apps. If you want to support us to improve Tinkerwell, update your app to the latest version and enable usage statistics.

Build desktop applications as a web developer

Our course teaches you how to build, publish, and distribute desktop applications with HTML, JavaScript and CSS.

Learn more
Desktop Apps With Electron course