Angelo Stavrow [dot] Blog

Missives and musings on a variety of topics.

On Tuesday of this week, Smile Software announced that their TextExpander software would be switching to a subscription model. As a longtime user and big fan of TextExpander, I have some thoughts on this change.

Another bit of software that I'm a huge fan of, YNAB, made a similar switch at the end of 2015—no more desktop apps sold with traditional licenses, but rather a new web app with a yearly subscription.

They're hardly the first to abandon the paid-up-front/paid-upgrade business model. And it's not just a question of small software publishers that trying on a new pricing option to improve cash flow. Most famously, Microsoft and Adobe moved to subscription models for Office and CC, respectively. While Microsoft still sells traditional one-time-purchase licenses for Office, that may not be an option forever—it's clear that they want you to move to their subscription model.

Some believe that subscription models are the most logical conclusion for sustainable revenue. Certainly, it does make income more predictable: it more-or-less normalizes revenue across the fiscal year, moving away from the typical huge-spike-at-launch (followed by smaller spikes on paid upgrades) sales patterns. When a business can better predict income, it can better plan resource allocation and feature releases.

This is something that web-service businesses have been doing from the outset—monthly fees (with, perhaps, a discounted yearly fee) are the norm. I can only think of one service (Pinboard) that used to charge a one-time, paid-up-front fee (although even that has changed).

But charging a monthly fee does not sustainable revenue make.

At least, I don't think it does for a large segment of the market. Monthly fees are something that are far easier to justify when they're mission critical—which typically means software that helps a business improve cash flow. They can look at a cost/benefit ratio and determine that the net result is positive.

The vast majority of software does not fall in this category.

But I don't think this is the largest impediment for software publishers going to a monthly fee. An even more interesting problem that comes with transitioning to a subscription model is that it takes the renewal-timing decision out of users' control.

Nerds like myself will probably upgrade to the latest version of software the day it's released, but smart people will weigh the pros and cons and see if it's a worthwhile upgrade. Even if it is, a user can decide that they'll keep using the current version awhile longer, if only because it improves their total cost of ownership.

Sven Fechner illustrates this nicely in his tweet on the TCO of TextExpander Classic vs. TextExpander 6. Taken over a longer period of time, with the traditional pricing model, users could opt to upgrade every eighteen months or even two years (assuming yearly upgrades) and save even more money. Or, at least, improve cash flow a bit by delaying some upgrades so that they don't all fall around the same time of year.

Instead, with a subscription, what happens now is that I have no influence on when the lump-sum yearly payments will become due (unless there's an option for a monthly fee, I guess, but that's usually the more expensive option).

So, instead, I'm forced to create a “subscription software” budget category and start putting aside some amount to cover next year's fee—or worse, come renewal time, I'm taken by surprise when I see a the fee I forgot about charged to my credit card.

I can tell you this: as that subscription software category starts to grow, some hard choices will be made. YNAB will stay because the money it saves me is at least an order of magnitude over what it costs me. TextExpander? Well, it's a great utility, but I don't know that I can justify a yearly fee for it.

I get that it's tough for smaller/indie developers to make a sustainable income from their apps, but the reality of the market is borne out by the App Store: cheap/free apps are what get the downloads. So, businesses are forced to try new things, so that they can afford to keep making the software that we use and love. At the end of the day, the only people who are really willing to pay sustainable prices for software are software developers.

Paul Haddad tweeted some possible outcomes of TextExpander's pricing experiment.

While I think that subscription software is a phase that some parts of the industry are trying on for size, it doesn't have any staying power unless there's a radical shift in the way we consume software. Something like, for example, an App Store subscription. We're moving to music and TV/movie subscriptions anyhow; maybe—just maybe—one way to make this work would be to pay Apple a monthly fee for access to any app on the App Stores?1

An interesting note: Smile have made sure to clarify that TextExpander 5 will continue to be supported for at least one more OS X version. It's clear that they're listening to the feedback they're getting from their users.

  1. I realize that on the Mac, this wouldn’t work for apps like TextExpander, as they cannot break out of the sandbox restrictions required by the Mac App Store to do what they do.

Discuss...

When I hear ship it, or we'll fix it in post”, I get that the intended sentiment is that perfect is the enemy of done. But too often, this translates to I'm okay with shipping garbage.

There's a delicate balance to be struck between doing it quickly vs. doing it well, sure, but if you're having a hard time getting there, then maybe you've bitten off more than you can chew. And that's a whole other kettle of fish.

And it doesn't just come down to outwardly sloppiness, either. When it comes down to your shipped product, people won't necessarily notice features that didn't ship—but every lapse from perfection will be noticed, and will go against your credibility as a Maker Of Great Things.

GitLab has an interesting take on shipping. They have time-based releases (the 22nd of every month), rather than feature-based releases. If a feature isn't ready for the next point-upgrade, it gets pushed to the one after. No big deal. This way, the only thing that ships is what's truly ready from prime time.

I like this approach, and it works well in the continuous-delivery context of a web app, but I think the lesson applies more broadly, too.

Don't ship for the sake of shipping. It becomes pretty clear pretty quickly that the product is taking a backseat to the profits when you do so. And the product always has to come first.

Discuss...

Earlier this week, I had a chance to talk out my approach to learning new things in the context of Cocoa development.

I've always found that I learn best when I get to use it in anger, but when it comes to something as big and sprawling as the Cocoa framework, there's a lot of stuff to learn.

Given that I do the vast majority of my development solo, I've found that the best way to approach this is to break the framework down into manageable chunks, write a little project based around that chunk, and then ship it.


I wrote my first app, HoneyJar, as a first introduction to Objective-C and Xcode. IDEs like Xcode are generally pretty similar—at their core, they're text editors with some special features—but Objective-C looked like no other programming language I'd ever seen before.

- (void)doYouKnowTheMuffinMan:(TheMuffinMan)theMuffinMan;

(I saw this somewhere on Twitter and I wish I could remember who to credit for it!)

I also made the app iPhone-only, as this made for a much less complex platform as far as things like filesystems, window sizes, and interaction go.

I also took the opportunity to explore CocoaPods, adding some libraries to handle some view and viewcontroller tasks—I had my hands full trying to figure out the language and the platform. I also integrated HockeyApp into the beta version I was working on, to get feedback from friends.

Once I was relatively happy with the app, I revved it to 1.0 and submitted it to the App Store—again, something I'd never done before. HoneyJar was never expected to be some kind of successful product, but a few people have downloaded it, and I know it's been useful to me on occasion.


When Apple announced Swift, its new programming language, I got pretty excited. Swift certainly looked a lot more like the programming languages I was familiar with, and there was something really neat about “growing up” with a new language.

So, I started work on my next app, Per. Per was all about digging into Swift (which has changed dramatically since the app was written)—there are no external libraries used anywhere in the app.

I also used it as an opportunity to play with some animations when presenting and dismissing view controllers:

Per's unit-converter feature

This meant that I got to look into closures as well, again as a small chunk of their applicability.


Last week I wrote about writing for GitLab as a means of teaching myself more about their continuous integration features.

I'm now interested in working with fastlane tools, so I'm working on an app as a counterpart to a new article I'll be writing for GitLab. The app is relatively simple: it consumes GitLab's API to present some kind of a dashboard for project milestones that the user is involved in.

Because I want to focus on learning fastlane, I don't want to worry too much about handling API requests and responses, so I'm using a great library called Alamofire, and I'm making this a tvOS app.

Why tvOS?

Well, firstly, it's a new platform that I get to play with. That's pretty interesting in and of itself, because while it brings a standardized screen size, it also includes the Siri remote as the sole means of interaction.

But, additionally, an Apple TV assumes a persistent connection to the internet, which means one less thing to worry about: testing for a lack of connectivity (or worse, spotty connectivity).

This way, I can learn about a new platform and a new toolchain without worrying about other pitfalls and perils.


So that's how I like to learn: small, neatly defined chunks, where I can focus on the thing I want to find out about, and ship something that showcases what I've learned. I'd love to know what works best for you!

Discuss...

As I've mentioned before, I'm looking into re-working things a little bit for some of my “online presence”.

Right now my personal site is just a static landing page. It's generated by Hugo and links to other things (this blog, my Tumblr, GitLab/GitHub, Twitter, &cet.)—and I think it's time to start consolidating some of that.

This blog will be moving to a static-site generator soon, too (again, Hugo). The domain and all links will remain active, but I'd like it to also live under a /blog directory on my personal site. I'll continue to write longer-form posts here.

My Tumblr, Break Before Make, will shift roles to becoming more of a linkblog—I have a huge backlog of stuff in Instapaper that I want to start sharing, and I think this is probably a better option than starting a newsletter. I'd also like to pull those posts into the /blog directory, between the MBB posts. It'll stay on Tumblr because I like its sharing capabilities via its iOS app.

I'm also think of adding /now and /using pages to my personal site, to discuss my projects and my tools, respectively. The former is supposed to keep you focussed on what you're doing, which I often need help with; the latter I'm not sure about, because really, I'm more interested in results than I am in tools—but maybe workflows will be of interest to some.

So that's the plan. Initially I'd hoped to have completed at least moving this site to a static generator by the end of February, but, well… time makes fools of us all.

More tk…

Discuss...

Yesterday, an article I wrote on setting up GitLab CI for your iOS projects was posted on the GitLab blog.

Now, I'm a relative newcomer to continuous integration, but I know that it's valuable. And I also know that GitLab's feature is free, regardless of whether your project is public or private.

I also know that the best way to learn something is to show someone else how to do it—so I launched BBEdit and took notes as I worked my way through the setup, with the intention of posting something here about my experiences.

Then I discovered GitLab's call for writers.

GitLab runs GitLab on GitLab to continuously improve GitLab

GitLab is more than just a version-control system. It's a community. I deployed their Community Edition on a work server back around v3 and it's been in use ever since, partly because it's nice to have your own internal DVCS, and partly because of the predictable roll-outs of new versions (every month, on the 22nd), which makes scheduled maintenance easy to plan for.

But the key reason is that it's always been more than just a DVCS. I've watched GitLab grow from its humble beginnings to, in my mind, one of the most interesting open-source projects out there.

And you can see the value of this kind of Extreme Dogfooding in the bug report response time and the cool new features that come around with every point release. But you also see it in their strategy document. And their team handbook.

It all starts with an issue

Whether talking about a bug report or a blog post, everything starts with the opening an issue.

After applying to their call for writers, I heard back from Heather, GitLab's Developer Marketing Manager, who assigned me to an issue on the topic. I proposed an outline of the post, and after some discussion and clarification on the topic, I forked the GitLab-website repo and began work on my draft.

Everything is done publicly, in the open. This means that everyone can contribute, and you can easily send links to conversations and drafts to peers for comment and review.

WIP it good

And so the writing commenced. A few days later, I opened a Merge Request with a commit of my first draft. By adding [WIP] (Work In Progress) to the MR title, GitLab prevents it from being accidentally merged to the master branch until the diff has been discussed and reviewed by the team.

Heather started with a first review of the post for general formatting and style according to the Style Guide, made a patch to correct some line breaks, and then assigned it for technical review to Kamil, author of the GitLab Runner.

Kamil made some comments and asked some questions; I responded and committed an updated draft, which updated the MR. These changes were reviewed, and the process continued until the post was ready.

At that point, all that was left to do was remove the [WIP] comment from the MR, and the post was ready to go up on GitLab's blog.

Which it did, yesterday.

Closing thoughts

Whenever I take part in some community event, I ask myself one question:

Would I participate again?

In the end, that's all that matters. I want to feel like I'm making a contribution, that I'm learning, and that the community I'm working with is working towards some positive change.

Contributing to GitLab, even with just a small blog post, feels that way. In fact, it's only increased my interest in moving my own projects to their service, and working with them towards improving GitLab however I can, be it bug report or blog post.

Actually, maybe I should start learning Ruby to contribute even more. 🤔

Discuss...

While I don't have much to post here this week, I have been writing a technical article over the last couple of weeks. The final draft was submitted yesterday and, barring any unexpected changes or delays, it should be published next week.

It's been an interesting experience, and I intend on discussing it for next week's instalment.

Until then, I'm trying to post fun little items and interesting links to Break Before Make more often, so feel free check check that out. 😊

Discuss...

I've been thinking a bit about people and some popular techniques that they use to try to improve the quality of their lives.

Specifically, I wonder if successful application of GTD, YNAB's rules, or KonMari—essentially, the curation of stuff (life, money, possessions)—might be self-selecting.

Curation is maybe a bit of a weak description. These are methodologies for the processing of inputs with the goal of (typically measurable) progress towards a desired state.

“Mind like water” and “roll with the punches” may sound hand-wavy and zen-like, but it's the result of discipline and rigour. I'm a pretty methodical person who does well with ritual and routine, so weekly reviews and giving every dollar a job “makes sense” to me.

I wonder, though, if some people just aren't naturally wired to ease into methodologies like these. In the same way that some people get comfortable faster with programming or geometry concepts than others, maybe there's something to the way we've gotten used to parsing the world that makes it easier for methodical types to successfully apply methodologies.

I don't believe that programming or geometry is beyond the grasp of some subset of people because of their personality type or what-have-you. For some, the learning process needs to be adapted to better suit their understanding of things. For others, maybe practice makes perfect.

I think the same is true of methodologies.

When I'm struggling to understand or apply a concept, I look for one of two things: a re-framed explanation of some principle, or some kind of community support. YNAB does a great job of this, with their free classes, their community forums, and their blog. GTD does this with personal coaching and communities that build off of the system's flexibility.

That's probably why they have staying power, rather than just being some fad life-hack.

Discuss...

I rarely get sick, and when I do, it seldom lasts more than 72 hours. Having just recently gotten over a nasty cold, however, I have a couple of thoughts on the matter of working through cold and flu season.

Inevitably, there will always be someone who feels that they can't, for whatever reason, afford to take a sick day. So they load up on decongestants, fight their way in to the office, where they basically fill a seat with their butt, a trashcan with their snotty tissues, and their workplace with their germs.

Now, in many cases, our patient zero may legitimately feel that their paycheck is threatened by them taking a sick day. This is a failure of their corporate culture: if you're going to get fired for catching a cold, you're going to get fired for myriad other reasons. Resign yourself to that fact, stay home, and maybe start looking for something new.

For some others, it's a point of pride to show how responsible and diligent they are by coming in and struggling through the day. Look at how hard they try. Poor thing. They should be home resting, but instead they came in because they've got work to do. What a team player. What a hero.

What a jackass.

Because no matter how careful they are keep the environment hygienic, they become a transmission vector for whatever they're carrying. Which means their coworkers will get sick. Got a coworker with a depressed immune system? Welp, they're screwed.

There's a saying about the fine line between heroism and stupidity. This is a fine example.

Stay home. Get well.

If you have the energy for it, maybe keep up with some email just to stay abreast of what to expect when you get back.

But energy is probably in short supply. You simply can't be productive, efficient, and creative when your head is packed full of mucus. Don't try; you'll frustrate and stress yourself out even more.

So: Netflix and sleep. Plenty of fluids. NyQuil is my personal weapon of choice in the battle for my sinuses.

As you start feeling better—and if the work you do allows for it—maybe do some work from home. Maybe crank out some of the tasks that are more like project overhead. Or take advantage of a quiet home to concentrate on some strategic or creative work.

Of course, this isn't possible for everyone. Point is, stay home until you're ready—and you're no longer contagious.

Then, come back and catch up.

There's almost never anything so urgent that the business will go bankrupt if it doesn't have your constant attention. This fact is diametrically opposed to the point of view that some managers have. Again, this is a failure of corporate culture.

But I digress: the point is, you're back, you're well-rested, and you're ready to tackle your inbox. You're operating at peak levels. You can plow through that backlog.

Yes, I know that I can say these things because I'm lucky to have a pretty generous (if unspoken) sick-day policy. Our team works hard and we're evaluated on what we get done, not the hours we put in. As a result, my stress levels don't go through the roof at the first sign of a sore throat because I might be getting sick—I just deal with getting better, then get back to work, rather than letting the stress make it worse.

More businesses should follow suit.

Discuss...

The January 28th episode of Under The Radar, Apps With Personality, left me thinking about just why software from bigger software publishers tend to be more… well, bland.

A lot of it surely comes down to the design-by-committee (or, in the worst case, design-by-accountants/lawyers) way of working that David and Marco alluded to, but I think there's something else worth considering.

Every business-school student has heard the (actually false) Chevy Nova “legend”, whereby GM execs scratched their heads in trying to figure out why sales of the car were so poor in Latin America. It serves as a warning against moving your business into foreign markets without doing your homework first. In 2016 parlance, it speaks to the importance of inclusivity.

While words that are homonyms across tongues may be the low-hanging fruit of localization, “personality” may be one of the most difficult. The personality created for an inanimate object often comes from cultural significance that may not be universally understood. Some of the animism described in the KonMari method—thanking your shoes for a long day of supporting you, for example—just doesn't translate well in Western consumer/capitalist society, where race-to-the-bottom market economics has associated the shoe with a thing to be disposed of, not thanked.

In the podcast, Carrot Weather was rolled out as an example of an app with strong personality.

And it is. That maniacal AI/robot has a charm a that keeps some users (myself included) coming back.

But how easily can that be localized? Even with good translations for the spoken quips, things like the secret-location Easter eggs are hard. Some might be universally understood, like the Moon, and some pop-culture references (see: Star Wars) might be almost universal, but is Mount Doom meaningful to someone in Ulaanbataar?

And therein lies the rub. An indie developer that wants to inject strong personality in an app often doesn't have the resources to localize said personality to all regions in which it will sell, and a large company will probably want to invest those resources elsewhere—especially with profitability on the App Store being what it is these days.

So, the former designs something as a result of their cultural context, with whatever lack of universality that may result. The latter “blands down” their design, in an effort to find some lowest common denominator.

Discuss...

I've been thinking about adding a second kind of post to this site every week: a selection links that I found to be an interesting read during the week.

More specifically, I'm thinking about maybe three to five links, with a few words of my own commentary. Those links might be to freshly-published items, or they may be an interesting article from an archive somewhere. I don't really know.

What I do know, is that I come across a lot of thought-provoking, inspiring, or fascinating pieces of writing, and I want a more permanent place to share them than the Twitter firehose, or the Facebook walled garden.

To that end, I'll be moving my own writing to a Monday post, and a link post on Fridays.

More to come…

Discuss...

Enter your email to subscribe to updates.