A Bit of SaaS Weekly: Squeeze Simplicity
This is a weekly newsletter on the Software as a Service world. Learning, building, and shipping. Written by Ethan Mick.
Friends don’t let friends pick us-east-1.
- AWS Proverbs
That is all. Continue along your US East 2 day.
The Best Bits
- Code Llama 2, an open-source LLM for coding.
- Add
dir=auto
to your inputs for automatic right-to-left orientation. - useMemo overdose (You know who you are).
- Do short sessions help security?
The Price of Complexity
It's hard to keep things simple.
Complexity is the natural state of software, and without care and maintenance, the code will devolve.
The hard part is knowing what is complex vs. simple and fighting against that complexity before it rears its head.
The first part comes with experience. Certain solutions are simpler than others. For example, monolith software is simpler than microservices. A single process is simpler than multiple processes. One thread is simpler than concurrent threads.
Over time, you'll get better and better at knowing which solutions are complicated. Sometimes, that will just require building the solution to get a feel for it. And sometimes, that complexity is worth it!
For example, setting up a GraphQL endpoint is more complex than setting up individual (perhaps RESTful) APIs. You need a GraphQL Schema, resolvers, and a server, all on top of the API endpoint. However, in return, you get type safety and the ability to request more or less data on the fly from the client. That tradeoff is often worth it.
This article (which inspired this post) talks about a team debating how to resolve their database being put under too heavy load. The options presented would resolve it but would also increase complexity by a lot. The simple solution (but not easy) was simply to track down performance issues in the code, optimize queries, and rewrite code to avoid expensive tasks.
This is a great example of fighting back against complexity. While other solutions might sound fun and exciting, they offered an irrevocable increase in complexity. Avoid that for as long as you can.
For Recast, I'm already annoyed that my converter process is a different service. But building out a more robust pipeline will increase the complexity even more, so I'll push what I have until it can't take it anymore.
Learn to Build SaaS
Just a single stream this week as I refactored the converters for Recast, the ultimate file conversion service. I've been doing some research into some of the most challenging converters, and I think there are some good solutions. I'll be looking to implement them next week at the latest.
Besides making subpages for specific conversions, I think I'll branch out shortly and build some auxiliary projects that'll help Recast. Things like user reviews and contact forms are prime targets for their own SaaS, and I can open source a lot of that.
Tech Tip
I've started writing tests for the converters to isolate problems earlier in the dev cycle. This is tricky because the converters rely on local executables that are installed. In production, that will be Debian. Locally, it was macOS. However, some of these programs are... really challenging to install. I simply don't want them locally.
This is the perfect use case for Docker! I've created a Docker image that contains all the executables that the tests need:
FROM node:18 as builder
WORKDIR /usr/src/app
RUN apt update \
&& apt install -y build-essential libjpeg-dev libpng-dev libtiff-dev potrace imagemagick ffmpeg pandoc \
&& npm install -g pnpm
COPY pnpm-lock.yaml package.json ./
RUN pnpm install
After you build this, the trick is to run the tests in the container without needing to rebuild it all the time. This is easily achieved with a volume mount, but that'll also copy in the node_modules
. This is a problem since the docker image and host are different OS's.
The fix is to add node modules to the .gitignore
file:
So they aren't copied into the image at all.
Then you need to shadow mount a directory when using the container so the node_modules
within the container is not overridden:
docker run --rm -v $(pwd):/usr/src/app -v /usr/src/app/node_modules -w /usr/src/app imagename:latest pnpm test
And now you can easily run tests in Docker without needing to rebuild the image all the time!
Cloud Chronicles
- YouTube Subscribers: 3,018 (+391 🎉🎉 in the last 7 days)
- Newsletter Members: 558 +41 in the last 7 days)
YouTube has been showing more people my "Buy and Sell SaaS" series, which accounted for a lot of new subscribers. Clearly, there is quite a bit of demand for really making money from building SaaS. The tricky thing is, of course, it's still not easy. Building a product that's worth money takes time, and it's impossible to do that in a single 4-hour video.
That being said, hopefully, there will be some more opportunities to intertwine building SaaS and cashing out.
Last Byte
- Ask vs Guess culture.
- Debugging hydration errors in Next.js.
- How a startup loses its spark.