How I built a MVP in 14 hours

In this blog, I share the process of developing the EaseMyInjury project, utilizing NextJS, TailwindCSS, Firebase, Trigger.dev and OpenAI's ChatGPT4 on top of the ShipFast boilerplate. I'll outline the reasoning behind my technology choices, the tools I employed, and the key lessons learned during development.

The idea

As many of you know, I'm super into CrossFit. Recently though, I had to undergo knee surgery, putting a dent in my regular workouts. But hey, I'm not one to quit — I needed to adapt all workouts of the day, but it's possible! So, last Tuesday, I sent a prompt to ChatGPT. I laid out my current injury, shared that day’s workout, and asked the AI for alternative movements. I even wrote with some typos 🙈

ChatGPT prompt

The output was insane, in a good way. The alternative exercises were practically identical to what my coach had in mind. After hitting my midday workout, I started thinking: Why not make this into a project? Not just for me, but maybe it could help others too. I kept the convo going with ChatGPT to brainstorm a bit more on the concept and define it properly. I was sure that I wanted to pursue this project!

The initial setup

I've worked on several new projects recently, and the initial setup always takes some time, primarily because I haven't yet created my own boilerplate repository. Recently, I came across Marc's ShipFast project. Seeing that it supports TypeScript and has an NextJS App router, I decided it was worth a purchase and building on top of it.

I took an afternoon off to dive deep into this project. My motivation was sky-high, and when Marc dared me to launch within a week, I told him I'd do it in just a few days—or ask for a refund. Following Marc's guide, I set up the project, secured an email, and got all my accounts in order. The Shipfa.st boilerplate is geared towards MongoDB, which isn't my forte. So, I opted to bring in my own lib files and connect to Firestore instead, where I'm more at ease.

Development of the MVP

After having the base setup, I started the development the landing page. My good pal ChatGPT was there to bounce ideas off and critique my copy. By taking bits of code from various templates, I managed to complete the landing page by the day's end. It includes the pricing section and a subscription button. However, instead of hooking it up to Stripe right away, all CTAs funneled users to a single point where they could input their injury and workout details to get immediate value out of the product.

EaseMyInjury first landing page

I spent the evening working on the project to achieve a runnable minimum viable product (MVP). The goal was to allow users to submit information about their injury, their workout, and their email address. The system would then use the OpenAI API to generate a customized workout and send it via email. Although the ShipFast boilerplate is built on DaisyUI, I chose to use shadcn/ui components due to my familiarity with it. This required some manual integration, as the two component libraries are not fully compatible. Overall, using ShipFast was beneficial, although the process could have been faster with libraries I was more accustomed to.

First submission form

In order to simplify my development, I consciously chose to omit a login mechanism and dashboard initially, focusing on getting a functional MPV live. After adding a few more features, like an online page for viewing generated alternative movements, the MVP was complete. I wrapped up around 4 a.m., going from zero to a working MVP in just 14 hours.

I shared the project in Marc's Discord community and promptly received insightful feedback from Marc Lou and Pat Tammaro. The value of participating in these communities became immediately evident.

Expanding MVP to a full product

The day after the initial build was a recovery day, so progress was slower than usual. By the end of the week, however, I had carved out time to work on a dashboard that would manage injuries and workouts. I utilized a TailwindUI template for the dashboard, the same one I'd used for my other project, Social Thumbnail Generator. Since I'd already converted the template into various React components compatible with NextJS, this implementation was quicker. Design isn't my strong suit, so using these templates was a big help. I did spend a good amount of time figuring out which existing components would fit my needs.

EaseMyInjury dashboard

After having the MVP running in production, I encountered a hiccup when trying to make OpenAI's ChatGPT4 work with an endpoint deployed on Vercel; the timeout limits were too restrictive. I then stumbled upon Trigger.dev, a service for running background tasks. It was the perfect solution. I set up a job to handle workout submissions from both the landing page and the dashboard. In a couple of hours it was live in production.

During the early stages of the MVP, it became apparent that the initial onboarding form was a bit cumbersome. I restructured it into a more user-friendly, step-by-step process, allowing users to easily select the affected body part and corresponding injuries.

Another important consideration based on my experience, letting users extract value from a product without requiring sign-up is crucial, albeit more complex to code.

As of now, the project has moved beyond the prototype stage and is a fully operational MVP. I've yet to implement a payment system, but that's next on the agenda once the app gains some traction and maxes out its free usage tier. This strategy keeps me from investing time in features that may not be immediately necessary, freeing me up for other projects.

Conclusion

This was the project that I shipped faster in my life, even faster than in hackatons!

My main takeaways to be able to ship MVP faster:

  • Focus on the core value proposition → in my case it was to share an injury and workout and receive an alternative workout that the user can perform.
  • Use templates and boilerplates to speed up your development → for me, the TailwindUI, Shadcn/ui and ShipFast were a tremendous help.
  • Use the frameworks and services you already know → instead of learning MongoDB or Supabase, I preferred to integrate with Firebase as I have a deep knowledge of it already.
  • Don’t over-engineer → implement first, iterate next. You will have time to improve it, just ship as fast as possible.
  • Keep to the bare minimum and don’t add all the bells and whistles → for example, I only added a login afterwards. The payment mechanism is still fake and will only be implemented if users really exceed the free service.

But most important, just ship! 🚀

If you want to keep learning how I ship my products, follow me or join my newsletter to get up-to-date tips and guides. I will start sharing more on the behind-the-scenes and some technical guides on the technologies I use.

Stay up to date

Get notified when I publish or launch something new!