Software Engineering

Minimum Viable Product (MVP), Vision, and CRUD

If I were to define my own definition for Minimum Viable Product (MVP) to be used in a textbook it would be the following: The set of features that is necessary to gain and maintain early users.

It doesn’t sound that hard, does it? Twitter? Users should be able to post messages, they should be able to follow other users, and they should have a feed where they see posts from users they follow. Stack Overflow? Users should be able to ask, vote on, answer, and comment on questions. A todo list app? Users should be able to create tasks and be able to check and uncheck them.

Creating MVP is hard because of one reason: Vision.


The creator of a product has a vision for what they want their product to be, what features it should have, and how it’s going to improve its users’ lives. It’s good to be ambitious and want a lot of features but it makes launching so much harder. Let’s look at Twitter again. Let’s assume the creator had the vision for retweeting and hashtags when they first created Twitter. To them, all these features are part of their vision of how great the website will be. “Imagine not having to copy and paste a Tweet to share it!” or “Imagine clicking any tag and seeing all the other tweets that have the same tag! Wouldn’t that be cool‽”.

To be able to create a realistic MVP, one must be able to put their vision aside and focus on the users and their needs. Of course users would love to have all these features but is it necessary to have them all at launch for Twitter to be successful? No. Users just need a platform to share short text posts on.

The challenge here is putting aside vision. How does one ignore the desire to create the best product possible? It’s the fruit of their labour. They will have spent months on it before they launch it. They want it to be the best it can be. Anything short of that is a compromise.

The answer, in my opinion, is simply to realize that the choice is not between launching with feature X or without it. Rather, the choice is between launching with the right set of features and seeing their vision come to reality slowly or being late and seeing their vision fail miserably.

Without this realization, there are no consequences to adding more features. Throw more features in. The more the merrier! Now, there is a risk associated with adding features that they can do without initially. That ought to make it easier to accept that their product will launch without their full set of features.

The CRUD Problem

Once the creator decides on an MVP, they might realize that their application does nothing more that create, read, update and/or delete (CURD) entities. CRUD is seen as being very basic. It’s almost an insult to call an application “CRUDy”. A task that’s “CRUDy” in nature is seen as simple and low effort. Back to Twitter. The basic set of features described above is very CRUDy. Users should be able to CREATE post messages, they should be able to CREATE follow relationships with other users, and they should be able to READ a feed where they see posts from users they follow. Of course they can DELETE posts too.

The problem arises when, after spending months working on an application, the creator realizes they have nothing but a CRUDy application to show for it. What were those months spent on? Was it all a waste of time? Were they slow? Are they inefficient? Probably not.

The likely reason for the application taking a long time is all the details that need to be ironed out. How many characters should a tweet be limited to? How are tweets in feeds sorted? You get the idea. And, if, at some point during development, they realize they need to change one of these details, the changes might not be trivial.

I’m afraid the solution to this is another realization: Users do not care what goes on behind the scenes and whether the product is “CRUDy” or not. All they care about is features. Build a product people want and they will stick around.

Software Engineering

Complexity in Software

When it comes to complexity, somewhere between Hello World and Google exists every other piece of software ever written. What makes one piece of software more complex than another? Lines of code might be an obvious answer especially considering the link above but I believe that complexity causes an increase in the number of lines of code not the other way around.

The number of components that need to play well together is directly proportional to complexity. Web applications need a database, a back end, and a front end. The front end is rendered, it asks the back end for data, the back end retrieves the data from the database, formats it, and sends it to the front end. Let’s think of software in terms of MVC. Even though the front end and the back end both seem to utilize a variation of MVC, for our purposes, we’ll consider the database to be the model, the front end to be the view, and the back end to be the controller. Most features involve changing all 3 components and they all need to work well, and work well together, for the feature to work. This adds complexity. Not only because there’s code whose sole purpose is to communicate with the other layers, but also because you need to test all three components together.

This applies to all software of the same category though but some pieces of software are inherently more complex than others. Let’s take the current side project I’m working on. It is, in its core, a very CRUDy application. Users are presented with things, they can save said things, and the things they saved are presented back to them. Simple, right? Well, sure, but that’s just the techy elevator pitch. The things need to be presented nicely, they need to be laid out in a meaningful way, the pages need to make sense, the things need to have other meta data associated with them, the things need to be imported from 3rd parties, and there needs to be a way to keep the things up to date. The list goes on, and on, and on.

The number of features in a piece of software is an indicator of complexity but it’s not enough on its own since features have different complexities. A list of featured items is not as complex as a recommendation engine. In the former, data needs to be retrieved from the database, aggregated, and displayed. A recommendation engine, assuming one is written from scratch, requires certain usage metrics to be saved and an algorithm to be written that determines what people are interested in with a lot of planning involved.

If lines of code are caused by complexity, and features don’t correlate 1:1 with complexity, then what determines complexity in a piece of software? Requirements do. Features have multiple requirements. Generally speaking, the more complex a feature is, the more requirements it has and/or the more complex each requirement is.

Let’s take the two example features above as an example. Both features display a set of things to the user. The first, a list of featured things, might have the following requirements:

  • Featured things must refresh every 10 minutes.
  • Featured things are things that are saved most recently by users.

Now let’s look at the recommendation engine’s requirements:

  • Each user sees a recommendation based on their own activity.
  • Similar things are determined based on what users save together.

They both have two requirements, how can we say that one is more complex than the other? That’s because requirements don’t map directly to code. The second requirement here involves creating new tables, code to save user activity, and a relatively-complex query to determine which items are saved together. More granular requirements and subtasks of a feature provide these details.

Once we get to very granular details like “create users table”, “create API endpoint to sign in”, “create signin page”, we have a pretty good idea of what the complexity will be but almost no one bothers to create such granular subtasks beforehand and that’s why when a developer sets out to build a “simple” application, they underestimate the complexity involved. This is also what makes estimating so hard but that’s another topic for another day.