MatthewOdette A blog

Day 3 - Zero to MVP in 30 Days - Product Hunt's Ship and Communities

Hey there! I'll be writing two posts tomorrow. In addition to the daily update, I’ll write up how I set up a slack channel to have a free feed of targeted content to prospect from and engage in. It pulls in updates from Reddit, Quora, Hacker News, Stackoverflow, and a handful of Google alerts.

This stream of content lets me jump into discussions to help build an early audience. And this helps prevent me from distracting myself on a bunch of tabs searching for new content!

Product Hunt’s Ship

I did pull the trigger on Product Hunt’s Ship. It’s not published yet, but you all can access it before I publish it if you like!

I’m holding off on promoting it because I’m far enough into scaffolding my app that I’ll be able to mock up some static screenshots for a landing page tomorrow. After looking at some of the more successful Ships, they all have landing pages available rather than using ship a tool to solve being at a pre-landing page stage.

I also pasted their widget on my personal website in case you’d like a look at how their embedded option looks.

More validation efforts!

And finally, I continued to message folks for validation in the two channels I was exploring yesterday.

But I also added on communities. An example of this is available on /r/userexperience. With communities jumping in with self promotion is definitely a no-no. I always message the community moderators before posting anything related to validating and idea. This is so crucial, as long as you explain the purpose of your post and make it within their guidelines, they’re usually happy to let you kick off a discussion!

As an example to work from, here’s the message I send to the mods of /r/userexperience:

Hey r/ux mod team!

I was wondering if a post asking the r/ux community about validating an idea would be within the subreddits rules?

I don’t want to share any external links or promotion. For context: I just started a “30 days to MVP” challenge, and I would love to have a discussion with the folks here just about ideas/needs.

A bit about the idea I’m looking at and my background, just in case that helps: I’m coming from a senior/lead support engineering position. In this role over the last few years I’ve seen a lot of pain coming from the visual user error experience (toasts, alerts, etc.) A trend is that errors get pushed for new features, and generally those error messages are abandoned until there’s a tipping point of friction from github issues and customers writing in needing a repeatable workaround.

I’m curious what folks strategy from different backgrounds are on tracking the user-visible error experience, and how they measure & iterate to make improvements.

Would asking about the above fit in ok? If not that’s totalllyyy fine! And thank you for reading :-) And I apologize for this running a bit long!

And with a positive response from that I fired off my post to the subreddit. Although this particular post, at the time I’m writing this, doesn’t have any replies yet. But it’s only a few hours old, and posts there do take a bit of time to get traction. Even if it dies off with zero responses, I would not have known that without trying!

Just do stuff, we need to find what works.

I’ve reached a few communities today, but tomorrow I’ll expand to Facebook groups and even give LinkedIn groups a shot.

Day 4 on deck

  • First iteration of a landing page on
  • Publish/promote the Ship page
  • More validation outreach
  • Publish an article on curating a list of content to a slack channel that you can use to engage your audience
  • Switching to some dev work when I need a change of pace, but I expect tomorrow will be light on the development side


Day 2 - Zero to MVP in 30 Days - Beginning validation and app buildout

Hi there! Today’s going to be on the shorter side as I’m still busy emailing folks. Also, I’d love to do a comprehensive post on my early validation attempts in a few days, after I’ve tried a few more channels.

The start of validation

I have three primary goals with this early stage of validation:

  1. Find which group of people have the best response rate
  2. Find which channel of sourcing these folks yields the best response rate
  3. Of course, find a real interest in my idea

#1 and #2 are to let me find one or two specific channels that work in terms of response rate, and double down in what works.

Yesterday, I mentioned there were 5 different groups of people I might sell this to. Today, I’ve focused my efforts on the two groups I assume will have the best response: UX leadership/seniors and Product Managers.

I hit my goal of reaching out to 10 targeted prospects, and even this small number turned out to be a great exercise in finding my audience. For the first few rounds, I’ll be testing two different cold audience channels: Leveraging Twitter search (you can search for tweets containing images which is super handy in my case: filter:image “error message”) Using this, I found companies who were having a recent influx of customers pinging support with errors could help fix. Blog posts about error messages This helped in solidifying who’s thinking about these user-facing error messages the most – authors were exclusively UX folks. I followed this breadcrumb trail to see what business either the authors or interested commenters belonged to.

So for my cold outreach, I had a blog post to discuss or a real example use-case from their customers.

Here’s a pixelated view of my prospecting spreadsheet:

There’s better ways to track this, but at this early scale a Google doc will do just fine!

Tomorrow, now that I have the beginnings of a method to prospect these two channels, I’ll push out messages to another group of folks. And I’ll message 10 people in a new channel, to begin opening up testing response rates from different sources in parallel to these two.

Scaffolding the actual app.

Yesterday I also mentioned I’d like to get a seed going for the app itself. A this point we want the pipes that can leveraged in any idea we might pivot into, so we scrap as little development time as possible if we kill this first idea.

I started out as a front end dev, and I’m most comfortable with JavaScript. So we’ll be going fullstack JS to make sure I can move fast, using technology I’m most familiar with (there is one exception, we’ll get to that!)

The (MEAN+extras) stack:

  • Angular 5+ on the front end (a frontend that requires Typescript will be a nice help while we’re building)
  • Bootstrap: it looks like we’ll go with the Nebular theme as a starting point.
  • Node on the backend with Express
  • MongoDB + mongoose (hosted on MLabs for the free development tier while we hack things together)
  • Auth0 for authentication, this will save a ton of time, and their technical content team is amazing.
  • Now, for the unfamiliar, something I’ve really wanted to put to use in a project is Redux. I know it’s only recommended for larger apps as there’s a lot of boilerplate and a bit of a learning curve. But, this inclusion is to sprinkle in a fun challenge. And the debugging options with a single source of state are awesome. We’ll use NgRx.

Tomorrow, day 3!

More validation, of course.

I think I’ll pull the trigger on Product Hunt’s Ship. I don’t like putting up a full landing page until I have static mockups for screenshots, so I’d like to test Ship as a pre-official-landing-page solution.

I’ll set up my authentication service in Angular to wire up Auth0, using some of Kim Maida’s awesome posts to help speed this along.

And I’ll try to fix my woodstove, ‘cause it’s cold in here.

As always if you have any feedback or want to chat my email is on the sidebar :-) Thanks for reading!

Day 1 - Zero to MVP in 30 Days - Idea number 1

For the first idea, I’ll be going with the “scratch your own itch” approach. In my last role as Senior Support Engineer, a pattern that came up over and over again was: toasts, those popup error boxes, causing customers frustration and confusion.

Customers would write in, often with screenshots of the same error. And the support team would try to find a workaround, letting our customers move past the error. To see what this looks like, go search Twitter for “Error Message” – it’s a constant stream of folks pinging support.

These repeated support touches are reducing lifetime customer value (the more they talk to support, the more they cost you in support hours), can contribute to or cause churn, and can even eat up a bit of engineering time when your support team makes duplicate or unnecessary issues.

Now. There are a lot of tools for logging scripting errors, whether they’re clientside or serverside. But tracking the visual errors that we author ourselves and present our users is a different story.

I present to you idea number one: a tool to track visual user-facing errors, how much they’re costing you, and a framework with the accompanying analytics to reduce the cost those errors.

Some use cases? Sure!

I was going to run off to Twitter or Google to look for examples of poor error experiences that would see an immediate benefit from this service. But as luck would have it, today I ran into a few perfect cases setting up DNS records and some other accounts.

For these examples I’m not picking on anyone in particular, but using timely and real examples I came across. We’ve all seen similar errors in services we use every day.

Namecheap - Example use-case 1:

Setting up DNS records in Namecheap, I ran into this goodie: (note: removing the trailing period in the records was just to recreate the error for screen capture)

So, where does our app come into play here? would detect and alert you on an uptick in this blank error displaying to your customers.. With the library active, you’d be able to replay the user’s session, similar to what you see in the gif. This would let you see exactly what the customer is experiencing and how they’re trying to get around the issue.

Then looking at the accompanying logs, your team could see we’re trying to update records with an expired authentication token.

With that, you could have your team push out a change to instead display a module explaining the session has expired and send them to the login page for reauthentication.

IFTTT - Example use-case 2:

I was trying to go back to edit the settings on an If This Then That applet. But, my simple change was not saving for some reason. (More on what these IFTTT’s are for in tomorrow’s post!)

With this it turns out we had a nice error message created for us. But it was hidden above the fold with no indication that I had an alert to help me fix the issue… Actually at first I wasn’t sure there was an issue.

How could help? A few different ways, we could detect that the user is clicking save multiple times, and we can detect that the only error message element loaded outside of the user’s viewport. How cool is that?

How might your team solve this? Shake the save button, disable it, and use a message near the submit button to let us know we need to fix and issues pointed out in the form above.

Awesome. But I’ll need my potential customers to get their engineering teams to buy-in, adding a new tool is more work for them, right?

Let’s see some sort of proof of concept

My bare bones proof of technical concept for the library teams need to install on their site.

Initial requirements for the library:

  • Be so simple to install, a copy and paster could get it done. Check.
  • Track when the customers desired visual elements (alert boxes, form errors, etc) exist in the dom. Check. MutationObserver’s are cool.
  • Track when those target elements are actually in the user’s viewport. Check. IntersectionObserver’s are cool.
  • If desired, record all dom changes and keys/clicks to replay the user’s session and see if/how they solved the error, contacted support, or abandoned their task.
  • If desired record, all console errors and network requests for the full picture.

Let’s see that. Note: this library will be invisible to the user, it’s just to record and pipe the sessions and data we need to help you recover value from your errors.

We initiate the library here with an array of CSS selectors that target our app’s specific error containers.

As a target element is added to the dom or revealed to the user after being hidden, we record the session and data. We’ll use our IntersectionObserver to make sure we aren’t repeating full recording of issues the user moves in and view.

And that’s the rough start of’s library! We can make it work technically, which was the goal of this exercise.

Now to look towards validation.

The benefit assumptions we’ll explore and use for validation:

  • Reduce the number of touches to support caused by your user-facing errors. Saving your team money by reducing support hours.
  • Reduce strain on users caused by error messages, looking to have a reduction in churn and maintain or even improve customer happiness.
  • Save some engineering time in the form of less duplicate or unnecessary bug reports created from your support team.

The who:

Initially, I suspect targeting SaaS companies with over some number of employees (40?) and over a certain age (>1 year?) will be the best use of my time. The team needs to be large enough, and the app old enough, that they could realize the benefits from this kind of error tracking in a short amount of time.

One thing that’s tripping me up though, and I’ll need to test by reaching out to folks: who is our most likely entry point to a buyer in an organization?

  1. Support leaders? They’re close to the itch here, and should have a pulse on how much friction user-facing errors might be causing their organization.
  2. UX members? They may have an active interest in seeing how users actually operate when they run into their errors. And desire a tools to analyze and improve that interaction.
  3. Project Managers? It’s easy to punch a search into Twitter and see a ton of folks writing in about error messages. Maybe reaching out to relevant PMs within organizations could work?
  4. Engineering? My instinct is to rule them out, but I should test the waters all the same. They already have a list of things they need to ship and a list of issues to fix. As long as an error message is being display to the user, and the error isn’t crashing the app for the user, they might not have interest in further analytics right away?
  5. Managers/Founders? I think this could work on the smaller side of my target customer, but not for larger orgs unless I can find someone who has publicly expressed a need/interest.

Who should I prioritize here?

Tomorrow, day 2.

Whew! That ran long and I do (so far!) need to rush these posts out the door, so I might make an edit or two when I get a fresh set of eyes on this.

For tomorrow, we’ll actually find and message some people to start our validation journey. The plan is to message 10 potential customers tomorrow. Ten may sound a bit low, but I’ll be leveraging some of that time to fine tune me sources or where to find potential customers and begin to layout a repeatable to scale up validation attempts.

I’ll also look towards scaffolding the tech for the actual app side of things. Now, we’re going into this knowing we could kill this idea quickly. This scaffolding will be the boring stuff needed for any app we land on: auth, user roles, front end framework/libraries, etc.

If you work at a SaaS company or have a project with users running into errors, how does this idea sound to you? Definitely happy to chat, my email is on the sidebar.

Thanks for reading!

Day 0 - Zero to MVP in 30 Days

I’ve decided to do make next thing!

I gave it a few week waiting period to make sure the excitement stuck beyond the initial honeymoon phase and to work out the logistics of focusing a lot of time on this challenge.

Why a day zero? To lay down some ground rules.

  1. 30 days will be on a rolling restart. I’ll be splitting my time between making the thing and validating the thing. If while validating the thing, I decide I need to pivot or kill the thing, the 30 days to build a MVP will restart.
  2. This aggressive retry+blogging cycle will have a hard limit of 60 days. If I don’t have some confidence in a validated idea after 60 days, I’ll pump the breaks and give myself an opening to move on.
  3. MVP for this challenge means: a product that is either accepting early beta users or has validation via pre-paying customers.

I want the flexibility of killing ideas I can’t validate to ensure I have the motivation for making it through at least 30 days of this challenge.

What will the blogging for this challenge look like?

I’ll commit to an update every day. Posts will likely be tiny on some days.

I’ll try to remain as transparent as I can with data and the daily happenings. This range of topics will include:

  • Peeking into half written Google brainstorming docs
  • Hearing about rejections while trying to validate an idea
  • Figuring out pricing
  • Technical challenges I’m running into.


Tomorrow we’ll talk about idea #1 and hustle to lay down a framework for getting things done.

How to Make a Donut Chart with gRaphael

This will be a quick post showing how you can add native support for Donut Charts to g.raphael by extending the Pie Charts JS. Alternatively, you can just clone my g.raphael repo on GitHub, but where's the fun in that?

This post assumes you have a working set of raphael and g.raphael libraries, which depending on your source can be a little tricky.

##Adding Donut Chart Support to: g.pie.js

Crack open your (non-minified) g.pie.js. The Piechart function already accepts an options argument: opts. We’ll extend this to include: donut (bool), donutDiameter (ratio 0.0 - 1.0), and donutFill (hex color code). We also need to set up default values so nothing falls through the cracks.

The begining of your Piechart function should resemble:

function Piechart(paper, cx, cy, r, values, opts) {
    opts = opts || {};

    var chartinst = this,
        sectors = [],
        covers = paper.set(),
        chart = paper.set(),
        series = paper.set(),
        order = [],
        len = values.length,
        angle = 0,
        total = 0,
        others = 0,
        cut = 9,
        defcut = true,
        donut         = opts.donut         || false,    // default to false
        donutDiameter = opts.donutDiameter || 0.6666,   // percentage of the pie charts width
        donutFill     = opts.donutFill     || "#FFFFFF";// the color of the donut 'hole'

        ... cont'd

Only three new lines of code so far – that’s not so bad.

Now, we need to draw our donut, if opts.donut === true. Let’s place this code just before the chart.hover method is defined. All this code needs to do is draw a circle over the pie chart, using our new options. Note that the charts radius (r) is multiplied by the donutDiameter to give us the width of our donut chart’s ‘hole’.

	// donut chart code
    if (donut) series.push(, cy, r * donutDiameter).attr({ fill: donutFill, stroke: opts.stroke || donutFill}));

Annnnd you’re done. The is a part of the raphael library and cx & cy are the center x & y coordinates of the pie chart.

##Making Donut Charts and Taking Names

Now let’s actually draw some donut charts. We’ll start super basic, mimicking g.raphael’s basic pie chart example.

Either start with the piechart_basic.html example from the GitHub repo, or make a simple html page that includes your raphael.js, g.raphael.js, and your shiny new g.pie.js.

Here’s the magic code that draws the pie chart:

// Creates pie chart at with center at 320, 200,
// radius 100 and data: [55, 20, 13, 32, 5, 1, 2]
var pie = r.piechart(320, 240, 100, [55, 20, 13, 32, 5, 1, 2]);

And here it is as a donut chart:

// Creates pie chart at with center at 320, 200,
// radius 100 and data: [55, 20, 13, 32, 5, 1, 2]
var pie = r.piechart(320, 240, 100, [55, 20, 13, 32, 5, 1, 2], {donut : true});

The (slightly boring) result:

Now your free to add all the bells and whistles you can to any g.raphael pie chart. Here’s a example with a legend, the value displayed in the center when a slice is hovered, and a bounce animation. The source can be found on GitHub.

window.onload = function() {
    // Creates canvas 640 × 480 at 10, 50
    var r = Raphael(10, 50, 640, 480);

    // Creates donut chart with center at 320, 200,
    // radius 100 and data: [55, 20, 13, 32, 5, 1, 2]
    var pie = r.piechart(320, 240, 100, [50, 20, 13, 32, 7], {donut : true, legend: ["Chrome", "Firefox", "Internet Explorer", "Safari", "Other"], legendpos: "east"});

    r.text(320, 100, "Interactive Donut Chart").attr({ font: "20px sans-serif" });
		// mouse over
    	function () {
        var that = this.sector;
        this.sector.scale(1.1, 1.1,,;

        pie.each(function() {
           if( === {
               tooltip = r.text(320, 240, this.sector.value.value).attr({"font-size": 35, "fill":"#000"});

        if (this.label) {
            this.label[0].attr({ r: 7.5 });
            this.label[1].attr({ "font-weight": 800 });

	// mouse out
    function () {
        this.sector.animate({ transform: 's1 1 ' + + ' ' + }, 500, "bounce");

        if (this.label) {
            this.label[0].animate({ r: 5 }, 500, "bounce");
            this.label[1].attr({ "font-weight": 400 });

Looking good:

##On deck

I plan on exploring and explaining g.raphael charts in more detail, fixing a few quircks along the way.