From PowerShell Script to App Store Pro: The Year-Long Journey to Audiobook Converter Pro
Every production app starts somewhere. Mine started with a simple question. Can I convert M4B audiobooks to MP3 while preserving chapter metadata?
What began as a PowerShell script to solve my own audiobook frustrations became Audiobook Converter Pro, a full-featured application now available on both the Mac App Store and Microsoft Store. The journey took a year. It taught me hard lessons about technology choices and fundamentally changed how I think about productizing personal tools.
The PowerShell Proof of Concept
The problem was straightforward. I had a library of M4B audiobooks that wouldn’t play in my cloud music services. As someone who loves running and commutes daily, I wanted my audiobooks in iCloud Music and YouTube Music alongside my regular playlists. Not some separate app. Not a different workflow. Right there with everything else I listened to during morning runs or the drive to work. More importantly, I needed to see which chapter I was on at a glance, the kind of information that matters when you’re three miles into a run and trying to remember if you already heard the part about the detective finding the first clue.
The initial PowerShell script was a validation exercise. Could this even be done? The script leveraged FFmpeg to convert M4B files to MP3, split each chapter into individual files, and embed metadata so apps like Apple Music would display proper chapter information. Clean. Simple. Theoretically elegant.
It worked. Sort of.
The script could recursively search through directory trees and convert files one at a time. But calling it “worked” feels generous when you actually lived with it. Slow doesn’t begin to describe the experience. Brittle might be closer. You needed a fair understanding of PowerShell just to navigate the thing without breaking it.
File naming conventions constantly broke the script. Hours disappeared into tweaking regex patterns to capture different audiobook naming schemes. Some publishers used dashes. Others used underscores. A few used both in the same filename because apparently chaos is a valid organizational strategy. The sequential processing meant leaving conversions running overnight, and even then you weren’t guaranteed success. One audiobook could take 45 minutes or more because chapters converted one after another, each waiting politely for the previous one to finish like passengers boarding a plane in the slowest group possible.
I used this script for almost a year. Every time I acquired new audiobooks, I’d fire up the terminal, cross my fingers the file names wouldn’t break anything, and let it run. Then I’d hope. Sometimes I’d pray. Occasionally I’d check back three hours later to find it had crashed on file number two.
The Decision to Build a Real App
The idea to create a Microsoft Store app sparked the journey from script to product. This wasn’t about scratching my own itch anymore. It was about seeing if others faced the same frustrations and whether I could build something worth their time (and mine, let’s be honest, because a year of evenings and weekends isn’t free).
I use both Windows and Mac environments daily, so building for both platforms made sense on paper. In practice, this decision came with a challenge I didn’t fully appreciate at the time. Maintaining two separate codebases with different technologies, different UI paradigms, different everything. But I digress.
Why Electron and Node for Windows?
Speed mattered. I had some familiarity with JavaScript, and Electron offered a path to quickly create something functional without learning an entirely new ecosystem from scratch. More importantly, I found Electron far easier to work with than WinUI for this type of application. WinUI felt like trying to assemble IKEA furniture with instructions written in a language you barely speak. Electron, at least, came with diagrams I recognized.
The ability to leverage Node.js for file system operations and spawn FFmpeg processes felt natural coming from PowerShell scripting. I could translate my logic without fighting an entirely foreign ecosystem. The mental model mapped cleanly. Read directories. Process files. Handle errors. Basic stuff that shouldn’t require a computer science degree to implement.
Why SwiftUI for Mac?
The initial plan was Electron for both platforms. Code once, deploy everywhere. The dream, right? Write it once, ship it twice, collect money from both stores. Beautiful in theory.
Reality hit hard on macOS.
Issues with in-app purchase modules and configuration quirks made the Electron approach untenable for the Mac App Store. After wrestling with these problems for weeks (okay, maybe a month, but who’s counting), I made a difficult decision. Go fully native with SwiftUI.
This was a stressful turning point. I had working code on Windows and suddenly needed to rewrite everything for Mac using a framework I barely knew. The learning curve wasn’t just steep. It was practically vertical. SwiftUI’s declarative approach differed fundamentally from the imperative JavaScript patterns I’d been using. Instead of “do this, then do that, then do this other thing,” SwiftUI wanted me to describe what I wanted and let it figure out the how. Philosophically interesting. Practically infuriating when you just want a button to work.
Both technologies presented significant learning challenges. Even now, reviewing and updating the code requires time to reacquaint myself with each platform’s quirks. I open the SwiftUI code after a few months away and spend the first hour remembering what ViewBuilder actually does and why I needed to wrap that particular element in a GeometryReader. Fun times.
What Code Could Be Shared?
Essentially just the conversion logic. Both versions use FFmpeg as the processing engine, and the core algorithm (split M4B, extract chapters, embed metadata, handle file naming) remains identical across platforms. The math doesn’t change. The audio processing doesn’t care whether you’re on Windows or Mac.
Everything else diverged. The UI, file system handling, user preferences, and critically, the monetization implementations all required platform-specific code. Every single piece of it. I wrote the same feature twice, in different languages, following different patterns, cursing different documentation.
Speaking of monetization, here’s where things get interesting. The Windows version sits behind a paywall as a full Pro version. This wasn’t the original plan. The UWP in-app purchase module for Node didn’t work as expected, and I lacked the energy to explore alternatives after months of development already invested. The Mac version uses in-app purchases successfully through StoreKit, but the Windows route became simpler out of sheer exhaustion. Pay once, get everything. No subscriptions. No freemium games. Just buy it or don’t.
Would I choose these technologies again? Yes. Now that I understand both ecosystems, I know they work. The initial pain was real (very real, the kind of real that makes you question your life choices at 2 AM), but the familiarity I’ve gained makes future updates manageable. I can open either codebase and actually remember why I did things a certain way. Progress.
Navigating the App Store Gauntlet
Getting approved on each store revealed wildly different experiences. Wildly.
Microsoft Store (Easy Approval, Confusing Everything Else)
The Microsoft Store approval process itself was surprisingly straightforward. My app sailed through without major issues. Submit, wait a day, approved. Simple.
Everything around the approval process? Confusing as hell.
The UI layout for Microsoft Partner Center made basic tasks unnecessarily complicated, like they designed it specifically to test your patience. Simple questions like “where do I upload this?” or “how do I update metadata?” required hunting through nested menus that seemed to reorganize themselves every time you logged in. Nothing stayed where you left it. Settings hid under dropdowns that hid under tabs that hid under other dropdowns. It felt like a game show where the prize was getting to submit your app.
Worse, setting up my developer account took over a month to resolve. Issues with account verification required multiple calls to customer support, each call involving explaining the same problem to different representatives who seemed genuinely surprised this was happening. “Huh, I’ve never seen that before,” became a phrase I heard so often it invaded my dreams. Frustrating doesn’t begin to cover it. I spent more time on the phone with support than I spent writing some of the core features.
Mac App Store (Seamless Setup, Strict Reviews)
Apple’s App Store Connect was the opposite experience. Creating my developer account was seamless. The interface, while dense with information, made logical sense once I understood the structure. Everything had a place. That place didn’t move. Revolutionary concept.
The approval process lived up to its reputation for strictness though. I faced several rejections, each one arriving with clear, reasonable feedback that somehow still made me want to throw my laptop out a window. Fix this privacy disclosure. Adjust this entitlement. Update this screenshot because the text is 2 pixels too small in the preview. Straightforward requests I could address, sure, but each rejection meant another week of waiting for the next review cycle.
Both platforms required code signing and sandboxing with proper entitlements. These weren’t optional suggestions. They’re fundamental to each store’s security model, and getting them wrong meant rejection. Learning these requirements took time, but YouTube videos from other developers who’d walked this path proved invaluable. Thank you, random internet strangers who documented your pain for our collective benefit.
Timeline (A Year Well Spent?)
From “code complete” to “live on both stores” took roughly a year. That includes the Swift UI rewrite, dealing with Microsoft account issues, multiple Mac App Store rejections, and learning two entirely different submission processes while maintaining a day job. The year disappeared in a blur of evening coding sessions and weekend debugging marathons where I’d convince myself “just one more hour” would fix everything. Narrator’s voice: it never did.
Was it worth it? Ask me after I see whether people actually use the thing. Right now it exists, which already feels like an achievement. Whether anyone besides me converts audiobooks with it remains an open question.
Lessons Learned (What I Wish I’d Known)
Design Early, Design Often
I went in with a concept based on a script. This created problems. Real problems, not theoretical ones. User interface decisions that seemed trivial during planning became architectural constraints during implementation. Features I wanted to add later required fundamental changes to how data flowed through the application, the kind of changes that make you question whether starting over would actually be faster than refactoring.
Design matters. Not just UI mockups, but system architecture, data models, and user flow. How information moves through your app. What happens when things go wrong (and they will go wrong). Where state lives. How components communicate. Sketch these out before writing production code. Use a whiteboard. Use paper. Use anything that forces you to think through the system before committing to code.
Technology Compatibility Is a Real Problem
The biggest surprise wasn’t how hard things were. It was discovering my chosen technology didn’t support critical features on certain platforms. The UWP in-app purchase issues on Windows weren’t edge cases or bugs I could work around. They were fundamental incompatibilities I discovered too late, after I’d already built half the Windows app around the assumption they’d work.
Research your technology stack against your target environment thoroughly. Obsessively. Don’t assume “works on Node” means “works everywhere Node runs.” Platform-specific implementations matter more than the documentation admits. Forums matter. Reddit threads from three years ago where someone hit the exact same wall you’re about to hit, those matter. Read them all.
Distribution Is Harder Than Development
Building the app? That was the easy part. Actually easy, not “easy if you ignore these twelve caveats” easy. Packaging, code signing, navigating store requirements, handling rejections, managing metadata across platforms, these consumed far more mental energy than writing the actual conversion logic. The code that splits chapters and embeds metadata? Maybe 15% of the total effort. The rest went to making sure Apple and Microsoft would let people download it.
Distribution deserves as much planning as development. Budget time for it. Budget emotional energy too, because rejection emails hit different when you’ve spent months building something.
Similar Apps Exist, and That’s Okay
After launch, several users mentioned similar apps already existed. This stung initially. I’d spent a year building something that wasn’t unique, pouring evenings and weekends into a solution that apparently multiple other people had already solved. Great.
But here’s what I learned, and this took a while to accept. Every app solves problems slightly differently. Some users prefer my approach to chapter splitting. Others like the parallel processing speed, which genuinely makes a difference when you’re converting a dozen audiobooks at once. A few appreciate the specific file naming conventions I implemented that match how they already organize their libraries.
Your app doesn’t need to be the first. It needs to be good at what it does and serve the people who find it. That’s enough.
What Got Cut from v1.0
Shipping meant compromise. It always does! The original vision included support for formats beyond MP3, AAC, and FLAC. I wanted comprehensive metadata editing features where you could tweak every tag, every field, complete control. Batch preview capabilities so you could see exactly what would happen before committing to a conversion. Customizable naming templates that let users define their own organizational schemes with variables and conditionals.
These “nice-to-haves” got postponed. Shipping a working product beat shipping a perfect one that never launched. Users can convert audiobooks now. They can split chapters now. The metadata works now. Everything else can come later, if there’s demand and if I don’t lose my mind implementing it.
What’s Next
Building Audiobook Converter Pro changed how I think about side projects. Every useful script now gets evaluated differently. Could this help others? Is it worth productizing? What would distribution look like? How much time would it actually take (and then double that estimate because optimism is a liar)?
The answer isn’t always yes anymore. But now I know the questions to ask and the work involved. That knowledge has value, even if it mostly manifests as me talking myself out of building things.
For Audiobook Converter Pro specifically, the roadmap includes connecting an iOS app to the macOS version, letting users seamlessly transfer converted files to their mobile devices without the iTunes dance or AirDrop roulette. Enhanced metadata editing features are planned, addressing user requests and filling gaps from the v1.0 feature cuts. Whether these actually ship depends on whether I can summon the energy to dive back into SwiftUI’s documentation and remember how state management works again.
Advice for Script-Wielding Developers
Sitting on a useful script and wondering if it should become a product? Here’s what matters.
- Validate early. Does anyone else have this problem? Don’t spend a year building before asking. Post in forums. Ask on Reddit. Send it to friends who might have the same frustration. Their enthusiasm (or lack thereof) tells you something important.
- Choose technology that aligns with your target environment. Research compatibility thoroughly, beyond the happy path examples in documentation. Ask in forums where people discuss real problems, not theoretical ones. Read documentation, then read the GitHub issues for that documentation where people explain what the docs actually mean.
- Design more than you think you need to. Architecture decisions made hastily will haunt you. They’ll wake you up at 3 AM six months later when you’re trying to add a feature that seemed simple until you remembered how you structured everything. Draw diagrams. Write pseudocode. Explain your approach to a rubber duck or a patient friend.
- Budget time for distribution. App stores, code signing, and metadata management aren’t afterthoughts. They’re core parts of shipping, and they take longer than you think. Always longer.
- Use AI and modern tools to shorten timelines. If I started today, I’d leverage AI assistance far more aggressively. Development takes long enough without reinventing solved problems. Let the machines handle the boilerplate. Let them suggest the regex patterns. Save your brain power for the actually interesting problems.
Most importantly, be prepared to design. A lot. The transition from "script that works for me" to "product that works for strangers" requires thinking through edge cases you never considered. Error states you never encountered because you knew not to do that specific thing. User experiences that make sense to someone who doesn't understand how audiobook metadata works. You become a UX designer whether you wanted to or not.
Get Audiobook Converter Pro Today
Audiobook Converter Pro is available now:
- Mac App Store - Download for macOS
- Microsoft Store - Download for Windows
- Learn More & Features - Explore full feature set and specifications
If you've struggled with M4B format restrictions or need to convert your audiobook library, try Audiobook Converter Pro today. And if you're a developer with a useful script gathering dust in a GitHub repo somewhere, maybe this is the push you needed to turn it into something more. Or maybe it's the cautionary tale that convinces you to keep it as a script. Either way, you're welcome.
*Want to follow my journey or ask questions? Find me on Twitter *


