Picture of Michael Lee
:wave: Hey hey, I'm @michaelsoolee! I'm a full-stack developer, maker of one too many side projects and dad.

Business lessons from a lemonade stand

Written on August 21, 2019

Yesterday was Duke University’s move-in day. I work two blocks away from Duke University so the streets around Duke were a little backed up on the way to lunch.

While driving up a road that runs parallel to the campus, I noticed a little sign near a street that ran perpendicular to the street that I was on. It read coffee & donuts for sale. Within a few feet was a table with two kids — perhaps in elementary school — and an adult. On the table were stacks of Krispy Kreme donut boxes and pitchers of coffee. In front of the stand, an extremely long line of cars, seemingly stuck in gridlock.

I only glimpsed at this scene and took it in in a matter of minutes, but my mind started to fixate on as much of the scene it had registered. As I thought about it more, I couldn’t help but extract business lessons from this simple scene.

Lesson 1: Running a business based off an existing idea is ok

As the title of this post goes, essentially what the kids and adult were running is the classic lemonade stand. But instead of a lemonade stand, they took the idea and put a slight twist on it.

Instead of lemonade, sell Krispy Kreme donuts and coffee.

Lesson 2: Instead of charging more for the same thing, charge more on a slightly different thing

I thought it was clever that instead of lemonade, they were selling coffee. While I think the raw materials in order to make lemonade and coffee cost roughly the same, the final product I feel have a different perception or value.

Afterall there are coffee shops by the dozens popping up but there aren’t specialty lemonade shops popping up. Coffee instantly feels like something you can charge more, thus you get higher margins.

Thanks to the likes of Starbucks, it isn’t uncommon to pay $5-7 bucks for a coffee when it probably cost cents to make it. A squirt of hazelnut syrup and boom, add an additional $0.50.

I also thought it was quite clever that instead of lemonade they decided to sell coffee. You see I would guess based on the license plates that I saw, probably the majority of the cars stuck in gridlock were from out of state. It’s also likely that those were parents who drove their kids long distances to get there and exhausted from the long ride.

Just getting to school isn’t the final goal, it’s get to school, find the dorm then help your kid unload and get settled in their new environment. What these parents needed was a pick me up. Coffee to give them a shot of caffeine and donut to give them a quick hit of sugar. A little pick me up to carry them through the traffic, finding the dorm and getting settled in.

Lesson 3: Know who you’re selling to

Tired, famished parents. No close Starbucks in sight. Cost to attend Duke University, according to their office of financial support, $72,000 a year.

I don’t know for sure, but based on where they were and what they were selling, something tells me these kids who were running their lemonade coffee & donut stand did their homework.

They knew the location in which they set up shop was going to be a high traffic area on Duke University’s move-in day. They knew coffee and donuts would probably sell better than lemonade and that they could charge more. They knew most of the folks were out of towners who needed a little pick me up to get to their final destination.

Lesson 4: Go where there is traffic

This coffee stand could’ve set up shop three or four blocks down from where they are, on a street that sees pretty light traffic. But they are at the mercy of luck to see any business.

But instead they took advantage of this street that seemed to be a mainline into Duke University’s campus on move-in day. Everyone who decided to come down that street had no choice but to slow down and probably make eye contact with the kids running the coffee stand.

It’s like girl scouts during girl scout cookies season standing in front of your grocery store. You have no choice but to make eye contact with them as they flash their boxes of yummy cookies. Making you feel guilty if you don’t end up buying at least a single box of cookies, every, single, time you visit that particular store.

It’s easier to set up shop near an established, high-ish traffic location instead of an isolated or a lesser traffic area and driving traffic there yourself.

It makes me think of online shops. It is easier to get your first sale on an established market place like Etsy or Amazon because they already have the traffic. But not only that, the traffic already has a high intent to purchase. As opposed to setting up your own online shop. Where you’d have to put in the work to send traffic and then you’re not guarenteed they’ll buy what you’re selling.

Lesson 5: You either want it or you don’t

I don’t recall if the kids gave out samples, but I could guess with a high level of confidence that they didn’t. The reason being of the scenario. The folks are stuck in traffic, but the stand was at the intersection and not further down the traffic line. Which means the potential customer has to still keep most of their attention on the intersection to gauge whether it’s their turn to cross. Not only that, you don’t want to be the car holding up traffic.

Being the driver, you’d have to make a quick decision, you either want the coffee and donut or you don’t. If the kids offered samples, the customer would try it. They would decide whether they wanted one, then a kid would have to run back and grab the consumables and a transaction would occur.

Instead you can cut out the sample and help reduce strain on the customer’s decision. A kid could walk up to a car and wave a cup of coffee and donut. The customer decides they want it. If they want more, the other kid runs out with extras.

If the kids and the adult was clever, they would’ve set up some form of digital payment. Cause who carries cash these days? Digital is so much faster and less of a hassle.

If the kids did offer samples, the customer could’ve easily been satisfied with the sample, got the value that they wanted and driven away. I highly doubt they would’ve gone away done their thing and thought, oh I’ll park and come back to the stand to now grab coffee and a donut. If I was a potnential customer, I would be like heck no I’m not going back to that street. I’m going to find me a nice local coffee shop with easy access and a lot more time to make my decision.

While I merely observed this interaction and some of it I imagined what it would’ve been like to be a customer of this coffee stand. I thought it was interesting the lessons that I was able to extract from this scene.

Such a simple business and yet it was able to hit on so many business lessons that I think folks — including myself — often overlook or don’t consider. It was a good reminder to think through some of these lessons the next time I have a business idea.

Random number generator

Written on August 15, 2019

This is a random number generator between two numbers. To use, give a number to the lowest number field and a number to the highest number field and press the Generate random number button to get your random number. The randomly generated number will be a number between the range of the two numbers and is inclusive of the two numbers.

Unregistering service workers in Firefox

Written on July 23, 2019

Not too long ago I downloaded an open source Rails application to my machine to see if I can contribute to it. One of the features that it has is a service worker. So that if and when a user’s Internet connection is lost, the service worker kicks in and provides for a branded experience.

Because the application was a Rails app, the service worker was registered on localhost:3000. What this led to was a bunch of error logs because whenever I fired up a different Rails application, Firefox — the browser I frequently use to do development — would think the service worker was for that particular application.

You would think the solution to fix this issue would be located in the developer tools, but it turns out it’s a browser setting.

  1. Type in about:debugging#workers in Firefox’s address bar
  2. Scroll down to the section labelled Service Workers
  3. Find the service worker you’re looking to unregister and click on the button Unregister

Better product creation through design collaboration :anchor:

Written on July 10, 2019

My buddy, Shaun has written a really informative article about design collaboration and how it can be used to yield better products. I’ve had the pleasure of working with Shaun in the past and his approach to collaboration and providing feedback was always a positive experience for me. I’m glad he was able to share some insights in how he and his team at Savvy utilize it to create products for their clients.

Collaboration with customers is as important as collaboration with other designers and team members. At Savvy, we keep our customer involved throughout the creation of their product. We take our time to explain options and have discussions with the customer to make sure we understand their thoughts.

This enables us to get buy-in from customers early on and work from clear beginnings and ends. Larger reveals aren’t big surprises, and no one gets to the point where they’re seeing work for the first time.

Looping in customers and having them part of the design conversation is a crucial step in the product creation process. I’ve found that by doing this, you don’t have a lot of surprises and there is less thrashing overall. Feedback is also easier to take.

Often, during a conversation with others, we think more about what we are going to say next rather than what others are saying. This impacts the feedback process, especially in design, because we often know what we want to say before hearing another opinion or solution.

When you choose to listen first and react second, it allows you to fully understand the feedback someone else is presenting and sets you up to go deeper — what is the perspective they’re using and the place they’re coming from?

One of the key skills I had to learn when joining an agency that works with multiple clients is to listen. I’ve found that often listening to a client’s problem allowed me to get to the real reason for their ask. From time to time I learned that what they ask for isn’t what their business needs and so it allows me to then respond with a solution that aligns with solving problems for a business goal.

If you work in an environment that is made up of teams of people across various disciplines, I recommend giving Shaun’s article a read.

Compile a site with Jekyll without installing Jekyll using Docker

Written on June 10, 2019

My current choice for running my site is Jekyll, a static-site generator written in Ruby. Since I ditched Wordpress back in 2013, I’ve been using Jekyll exclusively. It is a lot easier to get up and running on Jekyll instead of setting up Wordpress, it does still have some road blocks in getting it up and running.

Since 2013, there’s been numerous times that I’ve had to set up a new computer, which meant getting Jekyll up and running from scratch. That usually means installing Homebrew, rbenv, Ruby and then Jekyll and crossing my fingers and hoping that everything runs the first time. Not to mention also getting git configured so that I could commit back to the Github repo that has all the files for the site.

Last week I started taking another look at Docker. Docker is a technology that lets you run your application in containers all from a configuration file. This is mighty powerful because it allows you to avoid the old dev adage of, “It worked on my computer”.

With Docker I discovered that I could compile or even serve my Jekyll site locally without going through the entire fuss of getting Jekyll up and running on my local machine. Although you don’t have to install any Jekyll dependencies, there is the need to install Docker to get Docker running. But I’ve found it really straightforward because they provide an app which provides the CLI and setup.

Building your Jekyll project with Docker

Once Docker is installed and set up on your machine, you can build your Jekyll project by running this command from the command line within the project folder,

docker run --rm -it --volume="$PWD:/srv/jekyll" --volume="$PWD/vendor/bundle:/usr/local/bundle" --env JEKYLL_ENV=production jekyll/jekyll:3.8 jekyll build

What this command does is:

  • --rm automatically removes the container when it exits
  • --volume="$PWD:/srv/jekyll" takes the current directory indicated by $PWD and map it to the directory at /srv/jekyll within the container so that it could build it
  • --volume="$PWD/vendor/bundle:/usr/local/bundle" this option maps the contents of the current directory’s /vendor/bundle and maps it to /usr/local/bundle. The reason for this option is so that gems could be cached and reused in future builds
  • --env JEKYLL_ENV=production in various parts of my Jekyll project, I’ve designated for it to only render if it’s for production. For example analytics shouldn’t be muddied up by my local development. This sets the environment variable for JEKYLL_ENV to production
  • jekyll/jekyll:3.8 this tells it to use the jekyll:3.8 tagged version of the Jekyll container
  • jekyll build runs the build command for Jekyll

If you’re running this command for the first time, the image for this container won’t be on your system, so it’ll grab it from the Docker registry first before it runs the container.

Unable to find image 'jekyll/jekyll:3.8' locally
3.8: Pulling from jekyll/jekyll
e7c96db7181b: Pull complete
622c94c90cb1: Pull complete
5ab26e9d8a17: Pull complete
830997f3d72a: Pull complete
1956a4eaab3f: Pull complete
36a9759f9f2f: Pull complete
Digest: sha256:deb267df3f6c2b7604b0d5a5aabcb394eec1452a053e4297cf2fb13b125e0bcf
Status: Downloaded newer image for jekyll/jekyll:3.8

One thing I ran into was this warning,

Error: could not read file /srv/jekyll/vendor/bundle/gems/jekyll-3.8.5/lib/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb: Invalid date '<%= Time.now.strftime('%Y-%m-%d %H:%M:%S %z') %>': Document 'vendor/bundle/gems/jekyll-3.8.5/lib/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb' does not have a valid date in the YAML front matter.
       Invalid date '<%= Time.now.strftime('%Y-%m-%d %H:%M:%S %z') %>': Document 'vendor/bundle/gems/jekyll-3.8.5/lib/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb' does not have a valid date in the YAML front matter.

To fix this I had to modify my project’s _config.yml file. Within your project if you’ve got an excluded section defined, add vendor to it.

  - "package.json"
  - "README.md"
  - "publish.sh"
  - "vendor"

Now running the docker run command from above should work and you should see your site built within the _site folder within your project. If you’ve got your project versioned with git it’s probably also a good idea to now add the vendor folder to your .gitignore file.

Serving your Jekyll project with Docker

Instead of compiling if you’d like to instead serve your Jekyll site to do some local development, you can also do that using Docker by running this command,

docker run --rm --volume="$PWD:/srv/jekyll" --volume="$PWD/vendor/bundle:/usr/local/bundle" --env JEKYLL_ENV=development -p 4000:4000 jekyll/jekyll:3.8 jekyll serve

The only difference between the serve command versus the build command above is that I pass it an environment variable of JEKYLL_ENV=development, as I mentioned this is because I have certain sections of my site set up to build only in a production environment.

Upon running the command above, you’ll see the same output as if you had Jekyll locally installed on your computer,

ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-linux-musl]
Configuration file: /srv/jekyll/_config.yml
            Source: /srv/jekyll
       Destination: /srv/jekyll/_site
 Incremental build: disabled. Enable with --incremental
                    done in 19.698 seconds.
 Auto-regeneration: enabled for '/srv/jekyll'
    Server address:
  Server running... press ctrl-c to stop.

Only difference is now, your Jekyll project is being generated and served from the Docker container and you can point your browser to localhost:4000 and see the Docker served site.