DEV Community

Cover image for Publishing an Electron AI App to the Microsoft Store: Everything I Got Wrong
Aykan KÖMÜRCÜ
Aykan KÖMÜRCÜ

Posted on

Publishing an Electron AI App to the Microsoft Store: Everything I Got Wrong

I published a Windows desktop AI assistant to the Microsoft Store as a solo developer. It took two submissions, one rejection and a handful of undocumented surprises.

This is the list I wish I had found before I started.

Why the Store at all

I had a working NSIS installer and a payment flow running through an external provider. The Store was not obviously worth the trouble. Two things changed my mind.

Microsoft signs the package for you. Without the Store, a Windows SmartScreen warning greets every single user on first launch, and the only way around it is a paid code signing certificate. For a solo developer shipping a privacy-focused product, telling users to click through a security warning is a bad first impression.

The second reason is the 2026 policy allowing non-game apps to use their own payment systems. My entire purchase flow lives outside the Store and none of it had to change.

Surprise 1: electron-builder ignores your icon for appx

My package.json had a perfectly good build/icon.ico. NSIS used it. The appx target did not.

Appx packages need PNG assets at specific sizes, and electron-builder will not generate them from your ico. You need a build/appx/ folder containing at minimum:

  • Square44x44Logo.png
  • Square150x150Logo.png
  • StoreLogo.png (50x50)
  • Wide310x150Logo.png

Miss these and the build succeeds but your app shows up with a blank tile.

Surprise 2: the runFullTrust justification field silently truncates

If your Electron app touches the filesystem, you declare runFullTrust and Partner Center asks you to justify it in a text box.

That box has a very low character limit and it does not tell you what it is. Long explanations get cut off without warning. Write two sentences, not two paragraphs.

Surprise 3: package size

My first appx came out at 526 MB. My second one, functionally identical, was 191 MB.

The culprit was the files array in my electron-builder config. **/* means everything, including development dependencies you never ship. Audit that array before you upload half a gigabyte.

The rejection: policy 11.16

My first submission was rejected. One reason, nothing else.

Policy 11.16, Live Generative AI Content. If your app produces generative AI output, you must give users a way to report inappropriate content, in the app, visible, one click away.

I had spent months on the privacy architecture. Zero data retention, no file uploads, local processing, provider-side data collection disabled. I had thought carefully about where data goes and not at all about what happens when the model says something wrong.

The fix took half a day:

  • A flag button under every assistant message, next to copy and read aloud
  • A modal where the user writes what went wrong
  • An endpoint that writes the report to the database and sends a notification email
  • No credit cost, because reporting a problem should never cost the user anything

Resubmitted. Approved in 24 hours.

Surprise 4: your app will pass certification and still be broken

This is the one that actually hurt.

My server spawned a child process like this:

spawn("node", [path.join(__dirname, "dist/index.js")])
Enter fullscreen mode Exit fullscreen mode

That works on my machine. Node.js is installed on my machine. It is not installed on my users' machines.

The app launched fine. The UI rendered. Nothing crashed. Certification passed. And every single user who typed a message got a sixty second wait followed by a generic error, because the child process never started.

The fix is one line:

spawn(process.execPath, [path.join(__dirname, "dist/index.js")], {
  env: { ...process.env, ELECTRON_RUN_AS_NODE: "1" },
})
Enter fullscreen mode Exit fullscreen mode

Electron ships its own Node runtime. Use it instead of hoping the user has one.

To verify the fix I renamed my Node installation folder, which makes the machine behave like a clean user machine:

Rename-Item "C:\Program Files\nodejs" "C:\Program Files\nodejs_off"
Enter fullscreen mode Exit fullscreen mode

Run your packaged app in that state before every single submission. Five minutes of testing against two days of certification turnaround.

What certification actually checks

Store certification is a compliance review, not a functional one. It verifies signing, manifest validity, declared capabilities, policy compliance and that the app does not crash on launch.

It does not verify that your app works. That is entirely on you.

Bonus: IARC ratings transfer

Filling out the age rating questionnaire produces an IARC Global Rating ID. That ID works across other IARC-licensed stores without redoing the survey. If you add a feature that would change your answers, you redo it.

The short version

  • Generate appx PNG assets manually
  • Keep the runFullTrust justification short
  • Audit your files array
  • If your app generates AI content, ship a reporting mechanism before you submit
  • Never assume the user has your development dependencies installed
  • Test the packaged build in a clean environment every time

The product is NeonCore, a Windows AI assistant that processes documents without uploading them anywhere. Built solo.

Top comments (1)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.