How to get installs for your Electron app
Getting installs for an Electron app needs two separate things: a distribution path (a signed, notarised build people can download and run) and an acquisition channel (a reason anyone arrives at it). Electron Forge and electron-builder solve the first entirely and the second not at all.
The short answer
You need two things, and they are different problems:
- A distribution path — a signed and notarised build, a download URL that works first time, and an installer that does not warn anyone. If this is broken you lose roughly half your installs silently.
- An acquisition channel — something that causes a person to arrive at that URL at all.
Electron Forge and electron-builder solve (1) completely. Nothing in the Electron ecosystem solves (2), and that is the gap this guide is about.
If you want the compressed version: sign and notarise, put the download one click from the homepage, then pick your acquisition channel by price point. Under about EUR 40 of lifetime value per customer, paid search cannot pay back and you should use content, communities and cross-promotion. Above it, search works.
Packaging and signing are necessary, and they create no installs
Worth stating plainly because a lot of launch effort goes here and it is table stakes rather than growth.
- macOS: notarise and staple. Check with
spctl -a -vvv -t install YourApp.app. An un-notarised DMG shows a Gatekeeper block, and most people stop there rather than right-clicking to open. - Windows: sign with a certificate that has reputation. SmartScreen reputation accrues per certificate over installs and time, so a brand new EV cert still starts near zero and warns.
- Sign nested binaries too, not just the outer bundle. A bundled
ffmpegor native module that is individually unsigned or individually flagged will take the whole app down with it. - Auto-update via Squirrel or the Tauri updater. Retention is an acquisition input: an app that cannot update itself churns, and churned users are installs you paid for twice.
None of the above makes anyone download your app. It stops you losing the ones who already decided.
Which acquisition channels actually work for desktop apps
| Channel | Cost | Setup time | Install quality | How you measure it |
|---|---|---|---|---|
| Content and SEO | Time, ~18 months | Weeks | High — intent-led | Search Console, then retention by landing page |
| Communities (HN, Reddit, Discord) | Time | Days | High but one-off | Referrer, plus a launch-day cohort |
| Directories (Product Hunt, AlternativeTo, SaaSHub) | Free | Hours | Mixed | Referrer; mostly a backlink play |
| Paid search | High, auction-set | Days | High intent, high cost | Cost per retained user, not per install |
| Affiliates and deal sites | 20–40% + discount | Weeks | Low — discount-led | Sale attribution, cookie-based |
| Curated bundles (Setapp) | Revenue share | Months | High, but not your customer | Bundle reporting only |
| Cross-promotion | Attention you own, or a fixed CPI | Hours | High — installers reaching installers | Signed token, 48h retention |
The decision that drives all of it is your price point. A EUR 29 one-time licence can afford roughly EUR 0.27 per click at a sane margin. A EUR 29/month product bidding on the same keyword can afford EUR 3.18. You are not outbid on creative; you are outbid on revenue model. The full arithmetic.
A 30-day launch plan
Days 1–7 — make the distribution path not leak. Sign and notarise both builds. Put the download one click from the homepage with no email gate. Test the full download-and-install on a clean machine for each OS. Add the ghan:// protocol handler now if you intend to use cross-promotion later; retrofitting it means waiting for another release.
Days 8–14 — beta users and the things only you can write. Twenty people who will actually use it and reply. Write the two or three articles that only someone who built this could write — not "top 10 tools", the specific technical problem you solved. These are the pages that still bring installs in year two.
Days 15–21 — directories and communities. Product Hunt, AlternativeTo, SaaSHub, and the two subreddits where your users already are. Expect a spike, and plan for the spike not to be a channel — launch traffic decays to roughly nothing within a week, and that is normal rather than a failure.
Days 22–30 — pick the repeatable channel. By now you know your price point and your retention. Above EUR 40 lifetime value, test paid search with a small budget and measure on cost per retained user. Below it, set up cross-promotion: you have an audience of people who demonstrably install desktop software, which is exactly the asset the channel is priced in.
Where GHAN fits
GHAN is the acquisition layer, not a packaging tool. It sits alongside electron-builder rather than replacing anything.
Member desktop apps show each other's install cards inside their own in-app lifecycle moments. You show other members' cards; they show yours. You earn 70% of the rate card for every install you send that survives 48 hours, and you spend it — or cash — on installs of your own.
What this is not: an offer inside your installer. That is the pattern that got OpenCandy and ironSource installcore flagged as malware, and GHAN has no installer-time slot at all. Placements are in the running app, at a moment your code picks. The history in full.
How the attribution works
Click issues a single-use token, signed, expiring in 15 minutes, bound to the campaign and the serving app. It travels two ways — a ghan:// protocol handler invocation and a local handoff file — because a browser download followed by a manual install loses a URL fragment.
On first run the receiving SDK finds the token and countersigns the claim with its own ed25519 key, generated on that machine and never transmitted. Two independent signatures are required before anything becomes billable, and you hold one of them, because it came out of a binary you compiled and signed.
Money clears only if the install is still in use 48 hours later. No fingerprinting, no probabilistic matching, no fallback. Full mechanics: desktop install attribution.
Integrating in an Electron app
npm install @ghan/sdk
npx @ghan/sdk init # writes the wiring, leaves a reviewable diff
import { ghan } from '@ghan/sdk'
await ghan.init({
appId: process.env.GHAN_APP_ID,
consent: settings.analyticsConsent, // nothing emitted while false
exclude: ['com.competitor.app'],
maxPerWeek: 1,
})
// Your code decides the moment. Nothing renders unless you call this.
await ghan.slot('first_success')
Register the protocol handler in your builder config so attribution survives the browser hop:
{ "protocols": [{ "name": "GHAN", "schemes": ["ghan"] }] }
Tauri is identical except the deep-link plugin handles the scheme. Full surface: SDK quickstart.
Letting a coding agent do it
Point your agent at the GHAN MCP server. It can read the public rate card before committing to anything, register the app, read back gate failures as stable codes with eligibility dates, fetch the integration guide as a function call rather than scraping a docs site, wire the SDK and open a PR, then create campaigns and audit the ledger.
Two steps stay human on purpose: you ship the release containing third-party code in a binary you sign, and you set the spending ceiling once. Full walkthrough.
What to measure, before you have any numbers
GHAN is pre-launch, so this guide will not quote network statistics it does not have. What you should instrument on your own side from day one:
| Metric | Definition | Why |
|---|---|---|
| Download-to-install rate | Installs started ÷ downloads | Catches Gatekeeper and SmartScreen losses |
| Install-to-first-success | Reached the app's core action ÷ installs | Catches onboarding failure |
| 48-hour in-use rate | Still used at 48h ÷ installs | The only honest denominator for CPI |
| D7 / D30 retention by cohort | Per acquisition channel | Where channels separate |
| Token acceptance rate | Claims with a valid token ÷ referred installs | Catches a broken protocol handler |
| Cost per retained user | Channel spend ÷ 48h-retained installs | The number that corresponds to revenue |
Most teams have never computed the last row, and it typically differs from reported cost per install by a factor of two to four. The measurement methodology.
Questions people ask about this
How do I get installs for my Electron app?
You need a distribution path and an acquisition channel, and they are separate problems. The distribution path is a signed and notarised build, a download URL that works on first try, and an installer that does not warn people. The acquisition channel is whatever causes someone to arrive at that URL - content, communities, directories, paid search, or cross-promotion inside other desktop apps. Packaging tools like Electron Forge and electron-builder solve the first completely and the second not at all, which is the gap most founders do not notice until launch week is over.
Why does nobody install my Electron app even though it works?
Almost always one of three things. The build is unsigned, so macOS Gatekeeper or Windows SmartScreen shows a warning that kills roughly half of installs before they happen. Or the download page asks for an email before the download, which halves it again. Or nothing is bringing people to the page at all, which is the real answer most of the time.
Is electron-builder enough to get installs?
No. electron-builder produces a correct DMG, EXE, AppImage or deb, handles auto-update and can sign and notarise for you. That is the entire distribution half, done well. It has no opinion about who arrives at the download link, and nothing in the Electron ecosystem does.
What is the cheapest acquisition channel for an Electron app?
Cross-promotion, if you already have users, because the currency is attention you own rather than cash you have to find. If you have no users yet, the cheapest real channel is content and community, which costs roughly eighteen months instead of money. Paid search is only viable above about EUR 40 of lifetime value per customer, because below that you are outbid by subscription products on the same keyword.
How do I know which channel actually produced a retained user?
By making the channel produce a signed, single-use token at click time that the installed app presents back on first run. Anything weaker - a UTM parameter that dies in the download, an IP-and-timestamp guess, a "how did you hear about us" field - either loses the link or invents it. See the attribution guide for the mechanics.
Does cross-promotion work for Electron apps specifically?
Yes, and Electron is the primary target of the GHAN SDK because it is the bulk of indie desktop software. The integration is one dependency and two calls, and the lifecycle slots are places your own code decides to show a card. Tauri and plain Node desktop apps are supported identically.
Machine-readable versions of this page: markdown · llms.txt · llms-full.txt · OpenAPI · AI catalog