Who doesn’t love a good stack teardown? Ever since I saw Cushion’s running costs page, I’ve been low key addicted to reading about how other apps are built.
I work on an app called SongRender that helps musicians and podcasters make videos for social media. So in the spirit of the teardown, here are the tools and services I use to run it!
This isn’t an exhaustive list — I’ve omitted some obvious ones (like HTML) and ones that are implied by other tooling choices (like HCL for Terraform).
- SCSS — A superset of CSS with cool features like mixins and nesting. I use it for both the marketing site and — with CSS modules — the web app.
Build Systems and Frameworks
- React — The frontend is a single-page app built with React, which has been a great choice — it gets out of the way and lets me just work on the app. There might be other frameworks out there that are quote unquote better, but the sheer size of the React community means I basically never run into any uncharted territory.
- Create React App — A batteries-included build system for React. The first time I made a React app, I cobbled together the configuration for Webpack/Babel/etc myself. Create React App hides all that — with the option to “eject” and get the full configuration if I ever need to do something it doesn’t support.
- Express — A Node.js server-side framework. Just like with React, I chose it because it’s the most popular by far. As for why I chose Node.js rather than another language, it’s because I need to run the same video rendering code in the browser and on the server.
- Hugo — A fast static site generator written, used to build the marketing site.
This list is also not exhaustive, but there are too many libraries to name them all here, so I’ve tried to keep it to the most notable or interesting ones.
- immer — An intuitive, performant way to do immutability. It can also serialize patches you make to an object, so it’s fairly easy to implement undo functionality as well.
- downshift — A React library for building accessible dropdowns and multi-selects. Easy to style, and you get accessibility for free.
- popper — A nifty little tooltip positioning library.
- node-canvas — Node library for using the canvas API on the server.
- ffmpeg — Swiss army knife audio and video library. I use this to on the server convert audio files to WAV and to combine individual frames into users' videos.
- Namecheap — Domain name registrar. Don’t get turned off by the slightly sketchy name — they’re my favorite registrar that I’ve used.
- Cloudflare — Provides DNS, SSL termination and DDOS protection for the websites and API.
- Netlify — Hosts static files for the app frontend and marketing site. It’s really easy to use and there’s a generous free tier.
- DigitalOcean — Cloud infrastructure provider, but with plain Linux servers rather than proprietary services. I use them for servers, databases, and object storage to host users' file uploads and videos. Their web UI and API are both really easy to use; I never want to go back to AWS. 💰 Affiliate link
- Postmark — Transactional email provider. I switched from SendGrid when I exceeded their free tier and couldn’t get in touch with support, and boy am I glad I did. Postmark’s delivery rate is better, and the dashboard is faster and easier to use. If you’re a bootstrapped startup, they’ll give you a $75 credit.
- PostgreSQL — Relational database for persisting the app’s data. I briefly considered MySQL as well, but PostgreSQL has a bunch of really nice features like returning data from modified rows. I did not consider non-relational databases like MongoDB.
- Redis — Key/value store, only used for a task queue. Usually I would put this part off and just build a monolith, but CPU-intensive video rendering needs its own server.
- InfluxDB — Time-series database for storing metrics. See the section on monitoring.
- Ubuntu — The Linux distribution that the servers run. Like other parts of the stack, I chose it because it’s one of the most popular.
- nginx — A web server and reverse proxy, used here as a load balancer for the API servers.
- systemd — A daemon that manages the processes on the server, like Node.js and nginx. pm2 is another popular one, but it’s Node-specific.
I’ve previously written about how I deploy SongRender, so you can read about it in more depth if you’re interested. If you just want the high level, these are the tools involved.
- Terraform — An “infrastructure as code” tool, where you describe the infrastructure you want and it diffs with the infrastructure that actually exists. Kind of like React, but for configuration management. I love Terraform, and I use it to manage any infrastructure it supports.
- Packer — A tool for building machine images. This makes it easy to deploy servers with Terraform.
- Sentry — Error tracking. Picks up any uncaught exceptions in the client- and server-side code.
- Statuscake — Uptime monitoring, making sure the website and API don’t go down. Chosen for its generous free tier.
- Papertrail — Log management. It forwards system log messages using
rsyslog, so I can just use
console.login my server-side code and have it picked up. At some point I might try to switch to a service that supports structured logs, like Timber.
- Telegraf — Agent that collects metrics from the servers and forwards them to InfluxDB. It makes it very easy to get metrics on CPU/memory/etc without paying an arm and a leg for something like Datadog.
- Grafana — Metrics dashboard that displays data from InfluxDB and PostgreSQL. It’s easy to set up and use, and its visualizations are pretty.
- Indicative — App analytics. I was using Mixpanel, but I ended up exceeding their free tier — which was a shame, because I liked them a lot more. Might check out Amplitude when I have time.
- Fathom — Website visitor stats for the marketing page and app. It’s simpler than Google Analytics and only $15 per month for small sites. 💰 Affiliate link
- Google Search console — Analytics about Google searches for which SongRender has shown up in the results.
- Stripe — Credit card processing and subscriptions. I love using Stripe. Their APIs are so well thought-out, the developer tooling is great and their documentation and dashboard are beautiful and easy to use. Their support is also responsive and helpful. I had such a positive experience with them that I registered SongRender LLC with Stripe Atlas, even though it cost a bit more than doing it manually.
- PayPal — Additional payment option. As happy as I am with Stripe, I’m that unhappy with PayPal: their tooling is lackluster, their documentation is not comprehensive and their website is slow. It’s also clearly not meant as a payment option for in-app purchases — for example, if you’re a new merchant, they’ll hold payments for a few weeks unless you upload a shipping label, which I obviously can’t do. People seem to like having it as a payment option, though.
- Mercury — My business bank. One of the three options Stripe recommended as part of Atlas.
- Sketch — Vector graphics editor. I designed the SongRender logo using this, and I touch up icons with it too. I tend to go back and forth between this and Figma, which I also really like — but there’s still an appeal to using a native app that doesn’t store all my data in the nebulous cloud.
- Nucleo — Library of SVG icons. I bought the lifetime package years ago and have used it in basically every project since. 💰 Affiliate link
- SVGOMG — Nifty web app that cleans up and compresses SVGs. It’s basically a frontend for SVGO.
- squoosh — Nitfy web app that compresses PNGs and JPGs; the raster image counterpart to SVGOMG.
- VS Code — Not quite a text editor, not quite an IDE. Probably the best Electron app I’ve ever used. I keep checking out Nova out of a love for all things Panic, but it’s not quite there yet.
- Postgres.app — Simple free local PostgreSQL server for macOS.
- dbmate — Language- and database-agnostic migration tool.
- Gitlab — Source code hosting and versioning.
- Yarn — Alternative package manager for Node.
- Make — SongRender doesn’t need to be compiled, so this is just a task runner. Self-documenting Makefile snippets are super helpful.
- Postico — Great indie Mac app for querying Postgres databases.
- Insomnia — HTTP client. I use this sometimes when I’m working on the API and don’t want to worry about the browser. I also use it as a very crude admin dashboard: the API has a few admin endpoints for things like retrying a failed render, which I hit directly from Insomnia. Paw is a non-Electron alternative that I’ll spend the $50 on at some point.
- Transmit — File transfer app. I use this whenever I need to poke around object storage, since it’s much easier than using DigitalOcean’s web-based file browser.
- Crisp — In-app support chat. It’s the slickest, least obtrusive one I could find with a free tier. I’d like to switch to Intercom but can’t justify the cost.
- Trello — A kanban board for keeping track of bugs and features. A killer feature for me is the ability to add checklists to cards. Before I deploy a feature, I make an exhaustive checklist of cases to test. I’ve caught so many bugs this way; checklists should be a crucial tool in any developer’s QA arsenal. Checklists work! 💰 Affiliate link
- Notion — A repository for less structured note-taking.
- Fastmail — The email provider I use instead of Gmail. 💰 Affiliate link
- Acorn — Raster image editor. I mostly use it as a lightweight Photoshop alternative when I need to tweak screenshots.
- iA Writer — Markdown word processor. I use it to write blog posts.
Not every relationship was meant to live forever. These are all the tools that I’ve stopped using for one reason or another.
- Ansible — Provisioning and deployment tool. Replaced by Packer and Terraform.
- Let’s Encrypt — Free SSL certificate authority. Replaced by Cloudflare, which does this automatically.
- Healthchecks — Cron job monitor. Replaced by nothing; I refactored away all my cron jobs. This was pretty useful and I’d sign up again if I needed it.
- SendGrid — A transactional and marketing email service. Replaced by Postmark, which has a faster web UI and better deliverability.
- Mixpanel — Product analytics. Replaced by Indicative when I exceeded their free tier and the next tier up was too expensive.
- Gandi — Domain name registrar. I was a fairly satisfied customer until they followed up a data loss incident (which didn’t affect me, thankfully) with some of the worst customer service I’ve ever seen. Replaced by Namecheap.