One of my favorite things about being a developer is finding problems in my day to day activities and figuring out creative ways to solve them. Even if I never execute on a solution, I still enjoy thinking about it. Being able to do that is one of the reasons I absolutely love what I do.
The problem I’m going to be talking about today is a big one that I came across while developing a desktop app using the popular Electron framework.
It was a commercial app that (i.e. I intended to sell it to end-users), so I needed some sort of service that provided a way to easily manage my paid (and unpaid) users and enforce what they were allowed and not allowed to do within the app i.e. some sort of software licensing service. Preferably, the service would be something I wouldn’t have to host myself — SaaS, maybe?
I was already planning on using Stripe to accept payments and handle subscriptions, so it needed to easily integrate with their API, and definitely not provide its own way of handling payments.
Bonus points if it was a flexible JSON API, similar to Stripe.
So, I started searching for a suitable service.
And believe me, I searched for a good while.
But there was nothing.
Well, that’s actually not fair. There was a whole slew of “enterprisey” services; digital rights management (DRM) “solutions” that were built without a care in the world for your customer’s experience.
Some marketed the fact that they brick your app as a selling point.
I realized that most licensing “solutions” offer a terrible user-experience (UX) for customers, because that’s seemingly the “best” way to handle things.
“Input your 90 character license key, please.”
You shouldn’t require your customers to input and keep track of a tediously long license key that is meant for machine consumption.
It’d be so much smoother to on-board customers if they just needed to log in using a normal email and password. But nobody offered that kind of service.
And then you encounter things like:
“Your trial has expired, so we’ve locked down the software you desperately need in order to finish that project you got going. It’ll be $400, please. (Go talk to our sales team, then come back with your license key.)”
“I noticed you got a new computer. Congratulations! We’ve locked down the software and would like you to contact our support team. We just want to make sure you’re not stealing from us. We know it would be convenient to for you to manage your computer activations yourself, but that’s a no-go.”
Licensing shouldn’t be hostile to your customers.
It shouldn’t default to assuming everyone is a criminal.
And it definitely shouldn’t make buying additional licenses hard.
If your customer doesn’t have a license, it’s simple: offer them one. If they’re using your software on a new machine, prompt them to either purchase a license with additional machines or deactivate the old one for the new.
Save yourself the support burden and let them manage their own licenses.
Don’t screw them over because it’s “easier.”
My rule while searching was that if the navigation menu contained words like “solutions”, I would bounce. After all, I was building a simple app on Node.js and Electron. I didn’t need (or want) to bundle it with a separate installer or DRM service that would brick my app if used improperly.
And it needed to be cross-platform, which none of them were. It’s either they support Windows, or they support macOS. Linux? No way.
All these licensing “solutions” were just plain scary for somebody building a small product. I just wanted something simple — Stripe simple.
So after a few weeks of searching and actually trying a few of the enterprise products I found, I just said “screw it!” and threw together a licensing JSON API in Rails. It was nothing fancy; 1 database table, a few API endpoints and that’s it. I pushed it to Heroku and a week later, I was done with it.
Finally, I could get on with building my app.
And I did and everything was great.
But the licensing issue I originally faced still loomed in my mind.
“I can’t be the only one who’s been frustrated with this problem, right?”, I would say to myself as I finalized and released my app.
After much looming, I couldn’t stand not trying to fix it.
If Stripe, being frustrated with the previous state of online payments, could swoop in and disrupt the market by targeting developers, couldn’t the same be done for software licensing?
“Maybe”, I thought.
So I built an almost-MVP. And when I say “almost-MVP”, I mean that it wasn’t at all an MVP. I completely scrapped what I had more than once. I built the MVP, and then rebuilt the MVP, and then rebuilt the MVP again.
Like most side projects, it kept growing.
I thought I would never finish it. A few (reality: eight) months in and I had already tripled the original feature-set I had in mind.
But I really liked what I had.
So I took a step back.
“Validate your idea — your guess” is something I had read (and heard) over and over and over again from startup books, podcasts and blog posts. I knew that before I spent anymore time on the project, I should validate it.
So I built an “early access” website for a software licensing service that wasn’t even close to being finished. It was a single page with a mailing list sign up form. I put my designer hat on and created a brand that I thought may help me get some traction. And then I posted it on Hacker News, sat down on the couch and actually forgot about it.
Before bed, I thought I’d check in and see how the post was doing.
It. Blew. Up.
After all was said and done, I was on the front page for ~2 days and received hundreds of sign ups, lots of angry comments, and a few nice ones too.
(I was so nervous that I didn’t handle my responses to the critics very well, I admit. Some of my answers were incorrect, others I misread the questions.)
At first I thought maybe the way I presented the product was too ambiguous, causing people to flock to it because they thought it was a solution to a different problem—but no, after talking with some of the sign ups, they were all frustrated with the exact same problem as me.
My next step?
Nearly 6 months later (including a 3 month beta), I launched Keygen: a dead-simple software licensing API built for developers. It’s everything that I’ve needed in a software licensing API for my apps, and a little bit more.
There’s no gimmicky software you need to install.
Nothing that will brick your app. (Unless you do it yourself?)
No “enterprisey” language.
Just pure HTTP goodness.
Keygen allows you to license your software your way, but encourages a good UX for your customers. It does so by encouraging you to:
- prefer user-accounts over inputting raw license keys (though, you can still do that if you want, at the expense of customer sanity).
- treat license keys more like cryptographically secure feature-access-tokens, instead of something to be plugged into an algorithm.
- include ways for your customers to enjoy your software through in-app purchases and self-serve machine activation, not deadlock.
- treat your customers as people who like and want to use the product that you’ve created, not as criminals.
- iterate quickly and not waste time creating a licensing solution in-house, because that’s what often happens.
I’d love to hear your thoughts and feedback on Keygen, this post, my other projects, and whatever else you’d like to talk about! And lastly, if you found this post interesting, please share it so that other people can read it.