How I Built and Launched A Small Web App in 17 Hours
Tags: webdev, showdev, css, eleventy
Published: 2021-01-11 14:31:34

In this reflection post, I'd like to go over the tech stack used, reveal a few tricks, and provide some techniques for how to rapidly go from idea to launch for small projects.

On January 1, 2021, [I launched ButtonBuddy](https://dev.to/5t3ph/generate-accessible-button-colors-with-buttonbuddy-41mg) which is a small utility web app that allows you to:

> Learn what it takes to ensure your buttons or button-styled links have accessible contrast across all states and surfaces, then use the generator to check and adjust your button palette.

_Note: the 17 hours was not consecutive - I work full-time and am a Mom 😅 and I'm definitely not advocating for hustle culture. I use WakaTime which tracked the time spent_.

## Tech Stack

Take a minute to visit [ButtonBuddy.dev](https://buttonbuddy.dev) and do a classic "View source".

...Surprised you can see all of it?

That's right - this app isn't React, or even Angular or Vue. It's sweet, delicious HTML, CSS, and a bit of vanilla JS just for the generator bits. And check out that load time!

ButtonBuddy was built using [the static site generator Eleventy (11ty)](https://11ty.dev), with [Parcel](https://parceljs.org/) added in to assist with bundling the JS and allowing the use of ES6 features.

> If you're not yet familiar with Eleventy, I have many resources available on [11ty.Rocks](https://11ty.rocks)

The ease of use and customization abilities of Eleventy are what enabled going from idea to launch so quickly on this project (in addition to a narrow scope).

Let's go over a few key features of Eleventy:
- Zero-config by default and ButtonBuddy required only a minimum of [config changes](https://github.com/5t3ph/buttonbuddy/blob/main/.eleventy.js).
- 100% static output by default, meaning the initial structural build was done using the fundamental web languages of HTML and CSS.
- [10 templating languages](https://www.11ty.dev/docs/languages/) to choose from - ButtonBuddy leveraged Markdown, Nunjucks, and HTML
- Ability to mix templating languages, used by ButtonBuddy to be able to write the content in Markdown and output it in a Nunjucks template.
- Built on Node, making it easy to include Node packages and additional JavaScript as part of the built process, which was critical to producing the generator functionality.

As mentioned, I did need to extend the base Eleventy functionality by adding in Parcel. Credit for the setup steps here goes to Michelle Barker for her [eleventy-parcel](https://github.com/mbarker84/eleventy-parcel) starter.

## Tips For Efficiently Building A Small Web App

> **TL;DR**: Choose a stack you know, and create the semantic HTML first based on your top features. Then create and test for minimum functionality, and finally refine content and styles. Be OK with leaving room to grow and improve!

You will without a doubt always build something faster when you're more familiar with the tech stack you choose.

That said - the closer to "zero-config" your environment, the faster you can go from idea to progress toward your goal. A static-first environment like Eleventy can also speed up your structural development by skipping the decisions around state, components, props, etc if that type of architecture isn't _really_ needed to accomplish your goals.

For ButtonBuddy, I created a hit list of features. Then from that, I built a starting point for my information hierarchy using semantic, accessible HTML and Nunjucks partials. I didn't get too caught up in styling just yet, and left a few things placeholder.

Next, I did some research and selected a package to help with a key feature of this particular app, which was determining the contrast ratio between two colors. Open-source packages and starters can of course aid in efficiency as well, but the research is an important part of this step. A little extra time for research may save starting down one path and having to re-do it with a different solution.

The tip here is to do _just enough_ to find out if it's a go or no-go for any add-in packages you select. That is, build the minimum viable part of the functionality and any corresponding UI you need, and resist the urge to refine at this stage.

When building ButtonBuddy, this meant stubbing out a single color control to ensure that the package correctly checked the value against a hardcoded color value in my JS to provide back a contrast ratio. I then checked the ratio against a secondary tool for accuracy, and when it had an equal result, I continued on.

If you really are under a deadline - self-imposed or otherwise - consider what features will be the greatest impact for your time and the project goals.

For ButtonBuddy, it was important to provide enough features to be useful as both an educational tool and giving the user actionable feedback and results. And the functionality had to work together with the interface to be clear and usable, and in and of itself be accessible, including for mobile users.

I've mentioned it several times already, but semantic HTML was key to the efficiency of this build (and should always be a priority). 

Having Nunjucks templating available was also useful. I divided up the parts of the app into partials so that I could include them individually to focus on the generator vs the content, for example.

For the styling, you'll also see no traces of a CSS framework for ButtonBuddy. While a framework isn't a _wrong_ choice, it's also possible to quickly build up styles when you leverage repeatable patterns. This again is where having templating available and using semantic HTML was key.

> Need a little help upgrading your CSS skills? Check out my [Modern CSS](https://moderncss.dev) series to discover modern solutions to old CSS problems. You may also enjoy my 20 minute video course on [building a landing page with flexbox and grid](https://5t3ph.dev/grid-flexbox-lp).

Once the functionality was stubbed out, I completed writing the content and added a small navigation. Then I refined the branding styles, and honed the generator layout. The goal here was "good enough" for launch so that I could start gathering feedback, while leaving myself grace to continue tweaking or address any issues or bugs.

## Minimum Launch Checklist

Once the app works and you're happy with the look and feel, there's still a few steps to ensure it's launch-ready, even for an MVP:

1. **Complete `<head>` tags** including a meaningful `<title>` and `<meta>` description.
2. **Add social tags** as well, particularly Twitter and Open Graph tags inclusive _absolute URLS_ to preview images. You can review [the social tags in use for ButtonBuddy](https://github.com/5t3ph/buttonbuddy/blob/main/src/_includes/base.njk#L19,L26)
3. **Test** across the top browsers and on a real mobile device - you may find an issue not present when using dev tools simulators.
4. **Check in Lighthouse** to catch any low-hanging items related to performance or accessibility. You can do this [online](https://web.dev/measure/?gclid=Cj0KCQiA6Or_BRC_ARIsAPzuer8Mil21teCu7Mo5aj772jBseI4zC0T7uMJKkcRbODZ-OPHWb-sWajIaAnq1EALw_wcB) or with browser extensions.
5. **Double-check accessibility** using browser tools like aXe and WAVE (note that automated testing will not catch all issues).

> **[ButtonBuddy is on ProductHunt](https://www.producthunt.com/posts/buttonbuddy)** and your upvotes are appreciated! I'd love your feedback on ButtonBuddy, and this process 😊