YOU’RE NOW READING

My desktop app has been installed over 70 thousand times. Here’s what I learned.

calendar_today Posted 1 year ago · 8 minute-read · Technology

I have built a desk­top appli­ca­tion that is cur­rent­ly installed on over 15 thou­sand user PCs and has been used by over 70 thou­sand users in its life­time. It’s an Elec­tron app. Here’s a few points I’ve learned after years of hav­ing the app in pro­duc­tion.

  • Updates are crazy dif­fi­cult to get right for every­one.

    I’ve tried many ways to make updates work most of the time, but there’ll always be some­one that isn’t able to update their soft­ware. It may be their antivirus, fire­wall, or some­thing else going on with their PC.

    What I’ve come to find is that down­load­ing the entire installer pack­aged with the updat­ed bina­ries is the best way. If the user has been able to install the app once, updat­ing it should­n’t be prob­lem if updates are done this way. Installers usu­al­ly request admin per­mis­sions when being run, so this also clears up any per­mis­sion issues.

    The down­side of this is that depend­ing on the size of your app, requir­ing your users to down­load the whole app every time they update may be annoy­ing, you know? In my case, this was an Elec­tron app, so you can expect at least a size of 100MB. This should­n’t be a prob­lem in 2019, how­ev­er, the small­er the bet­ter.

  • Users will down­load fake/malicious ver­sions of your appli­ca­tion by acci­dent.

    There’s some real­ly bad peo­ple on the inter­net. Once an appli­ca­tion gains trac­tion and starts get­ting used more, some awful peo­ple will brand mali­cious apps with your app’s name.

    This is exact­ly what hap­pened to my app. Peo­ple start­ed report­ing fake ver­sions of the app, most like­ly spy­ware or virus. This is dan­ger­ous because it can harm your rep­u­ta­tion. And we all know how the inter­net likes to blow things out of pro­por­tion!

    One way to deal with this is edu­cat­ing users on what the installer and app itself should look like, pro­vide a hash of the orig­i­nal installer and inform users on how to check hash­es of files down­load from the inter­net.

  • Improv­ing lit­tle details of the UI every now and then keeps the app look­ing fresh.

    Every time I had to do an update, I made sure I includ­ed at least a few tweaks to the UI. Although a user might not notice it at first, I believe it’s a sub­con­scious thing. The app looks like it’s always evolv­ing and this will make the app live longer before it feels ‘too old’.

    “Oh look! That but­ton looks nicer”, “A sur­prise hal­loween theme? Sweet!” are com­ments I’ve seen about my app. For exam­ple, when Google went all “round­ed-cor­ners” with Mate­r­i­al Design, I added some round­ed cor­ners in the same way MD does them, mak­ing the app look a bit nicer than before.

    Anoth­er rea­son I intro­duce small UI tweaks in every update is to know what ver­sion of the app a user is run­ning when they sub­mit a screen­shot report of a bug. There’s been count­less times I’ve iden­ti­fied the ver­sion just by see­ing these small changes. No need to ask the user what ver­sion they’re run­ning if their screen­shot does­n’t show.

  • Try not to break your app after an update.

    Your update sys­tem might work some­thing like this: your app checks a remote serv­er for the lat­est ver­sion. If the app run­ning is on a low­er ver­sion, then down­load and install the update.

    Make sure you put this serv­er behind a domain name to mask the IP address, because you WILL change servers in the future, and you will most like­ly NOT have the same IP. At first I did not con­sid­er this, and I unfor­tu­nate­ly had to break the updater for pre­vi­ous ver­sions of the app since I had to switch serv­er providers, and there­fore, serv­er IPs.

  • Allow a way for users to sub­mit feed­back for your app.

    Val­ue your users! Pro­vide a feed­back form, an email address, Dis­cord serv­er or some­thing so they can tell you what they think about your app, and what they think should be added, or what they dread the most. They are the one that know the most about your app, after all.

  • Pro­vide a wel­come guide, or, prefer­ably, bake it into the app.

    My app has sort of a “guid­ed” tour once the user opens the app for the first time. Tooltips appear to show the user where to click next to do the most com­mon actions in the app. The user is also always capa­ble of clos­ing this guide if they wish.

    This makes a big dif­fer­ence in the amount of sup­port requests you’ll get. Not every­one may know how to nav­i­gate your appli­ca­tion!

  • Don’t let the plat­form or UI frame­work com­plete­ly choose your pro­duc­t’s LAF (look and feel) for you.

    My typ­i­cal exam­ple for this is Java Swing inter­faces. Sure, Swing might be easy to use, but the amount of cus­tomiza­tion you can do is pret­ty lim­it­ed with­out invest­ing a lot of time on build­ing cus­tom com­po­nents.

    My point is that it may be worth invest­ing in oth­er frame­works that allow more cus­tomiza­tion, so that you can make your app look like YOU want it to, and not let it be dic­tat­ed by a frame­work or native plat­form.

    A good idea is to mix native LAF and your own LAF. For exam­ple, if you’re devel­op­ing an app for Win­dows, Flu­ent design is killing it right now! Design your own but­tons, text, font, etc… but keep the frosty, translu­cent back­grounds. Take a look at native apps of the plat­form and how their UI looks, com­bine them with your own look.

  • Use a ver­sion­ing stan­dard for your app ver­sions.

    Using ver­sion­ing stan­dards makes your app’s ver­sions rec­og­niz­able and under­stand­able by every­one. For exam­ple, use and fol­low the Seman­tic Ver­sion­ing stan­dard. Basi­cal­ly, <Major>.<Minor>.<Patch>.

  • Pro­vide visu­al feed­back to your users using progress indi­ca­tors.

    When some­thing is hap­pen­ing, show a “Load­ing…” toast mes­sage, or some­thing. When a but­ton is pressed, make it move down a few pix­els to let the user know they pressed it. Use load­ing bars. Dis­able text inputs that the user should not be able to edit.

    Users also like to know when down­loads will fin­ish, so if your app down­loads stuff, make sure you show an accu­rate remain­ing time counter. We’ve all hat­ed down­loads that stall at 99% for two hours… and sud­den­ly, done!

  • Include infor­ma­tion about the app in an ear­ly screen of the instal­la­tion process.

    If your app uses an installer to install itself, make sure you let the user know in detail what they are installing. Let them know what infor­ma­tion is being col­lect­ed (if any) and what ser­vices the appli­ca­tion inter­acts with (pos­si­ble shar­ing this infor­ma­tion to). What ver­sion they’re installing. The main fea­tures the ver­sion has.

    Also leave con­tact info just in case the user has doubts about installing your app. Make the user feel com­fort­able about installing the app.

  • Test your app in every sit­u­a­tion imag­in­able.

    Although most devel­op­ers are bound to get sur­prised from bugs users encounter even after thor­ough­ly test­ing the app, here I am to remind you again!

    Test your app in every sit­u­a­tion imag­in­able: with­out an inter­net con­nec­tion (if it should be able to func­tion with­out inter­net any­way), in a sand­boxed environment/VM, with a few antivirus installed. Enable the fire­wall on the worst set­tings pos­si­ble. Try your app with low disk space. Assign a low CPU count to your VM. Make it as slug­gish as pos­si­ble. This might also be a great moment to improve your app’s per­for­mance on devices with low spec­i­fi­ca­tions.

  • Make it easy to com­plete­ly unin­stall your app.

    It sure is sad to see our users go 😥. But make sure you let them if so they wish… Users can get real­ly frus­trat­ed when a pro­gram does­n’t get unin­stalled prop­er­ly and/or leaves files behind.

    Most installer pack­agers gen­er­ate an unin­staller once the user installs the app (which is able to com­plete­ly sweep all files that are part of your app), so this should­n’t take too much of your time. For exam­ple, InnoSet­up or Install­Shield do this. If you’re devel­op­ing for Win­dows, be a good Samar­i­tan and make sure you get rid of any reg­istry entries your app cre­ates, if any.

    If they can unin­stall your app eas­i­ly, they will trust your prod­ucts more, and prob­a­bly try out oth­er apps you’ve made and be con­fi­dent that if it’s not to their lik­ing, they’ll be able to get rid of it eas­i­ly. Make the unin­stal­la­tion process as easy as pos­si­ble.

As you’ve seen, there’s a lot to keep in mind when mak­ing a desk­top appli­ca­tion. Your users need to feel com­fort­able using your app, so make sure you make it eas­i­er for them.

I’m still work­ing on the desk­top app to this day, how­ev­er, I’m work­ing on a com­plete redesign. It’s had pret­ty much the same design since 2016, and I thought our users might appre­ci­ate a com­plete refresh. How­ev­er, I’ll con­tin­ue to sup­port old­er sta­ble ver­sions, since not all users like change. Got­ta think about every­one.

As always, thanks for read­ing this post. See ya around! 😀


– Kedi