Upgrading Sagemont Tax Apps to Next.js 13

February 15, 2023  |  12 min read

Or why software is hard, and the Sagemont Tax Tech story thus far.
So, a little history. Sagemont Tax has been around for a little over a year and a half. I’ve been here a little over a year, contracting since December 2021, joined full-time in June 2022, and became CTO in January 2023. In that span, I’ve gone from helping with email going to spam to taking a role in company leadership and building out our next generation of Tax Tech software.

Part of what I’ve built here is our internal app platform. Allowing us (well, me, so far) to build out custom software solutions to solve company problems and inefficiencies with custom platform integrations, employee user experience improvements, platform enhancements through APIs, process automation, and more. Now, here at Sagemont Tax, we’ve taken the approach of growing and scaling the company and the company’s process by always using the right tool (which doesn’t always mean the best tool) for the job at the time, and incrementally improving and replacing the underlying systems.

At the beginning of scaling the company, it started with Monday is a fine tool for a small business team. Its no-code integrations make it easy to set up and allow even novice tech project managers to set up an effective process. Over time, we’ve optimized, built, rebuilt, tuned, and enhanced our Monday process to a point where it works for us. Now, Monday, I will say currently has its limitations in scalability due to a lack of visibility through audit or activity logs for actions like changing column order, changing column settings, and changing column restrictions/permissions. There is no API that allows one to sync full column settings from board to board, and there’s no inbuilt way to do so. On Monday, it’s helpful to be able to have a process span multiple boards. We built an enhancement to sync columns from board to board automatically by mirroring all column settings of a new column, but there’s no support for updating column settings across boards after the initial mirroring. The total result at scale is boards full of potentially different columns that may not perfectly sync with constant data integrity concerns. And, the need to build our own automated tests to work around Monday’s incompleteness. As with all tech problems, it’s solvable by writing more good custom software. But, that also costs person hours. Monday has worked well with us in hearing our concerns, and I’m sure in the future these holes will be patched and Monday will allow you to fly.

Now, we are moving onto a Salesforce integration that we are excited about helping us to keep growing and set us up for success now and in the future. We’ll be keeping for what it’s good at, and where the process is working, and we’ll connect those two. Sprinkle in a touch of Microsoft 365, add some Dropbox for Business, sauté with a little mixed Atalssian Confluence, Jira, and Bitbucket, add a healthy dose of Formstack, some Quickbooks as a sweetener, then add the amazing people that makeup Sagemont Tax, and baby, you got a company going. Recently, we added GoCo to the recipe to supercharge our human process, about which I’m very excited.


None of the above is incredible business magic. They’re good platforms doing good work with APIs to allow platform enhancements. At Sagemont Tax, we supercharge that by using Zapier that moves you forward which gives us incredible rapid integration power across all platforms (or even unsupported ones through webhooks) through no or low-code integration automation. Good people that can understand business processes can implement them without coding knowledge. It’s come to the point where we don’t consider a software platform without knowing it has good support on Zapier.

But, at the base of it all, to truly scale, you need custom software to do what’s not possible through the combination of all the above, to reduce Zapier costs when a Zap becomes core to the company, and to have a place to build software for your own customers, whether external or internal. So, much of the investment up until now has been supercharging our employee experience and toolset, which has in turn pushed our client experience forward. Now, it’s time to continue driving both those avenues of improvement as we continue to grow our business now and into the future.

And for us, that custom software that is the deep magic of it all is Sagemont Tax Apps. Sagemont Tax Apps is a serverless AWS-based front and backend originally built with serverless-nextjs with (my new favorite thing) AWS CDK to add additional AWS services. The frontend is Next.js, a React-based UI with a built-in API backend. Thanks to serverless-nextjs, that backend easily deploys and runs on AWS Lambda@Edge and AWS S3. Things were going great. Our platform was in place, the pipelines were set up, and we were ready to roll. Employees were seeing improvements in their daily workflows and the processes continued to scale. And then…

And then, being a tech guy, I started tinkering. I started assessing the state of our frameworks and deployments. First, I found out that tsdx, our framework for bootstrapping our code libraries, is dead. I ended up migrating to a maintained fork of tsdx called dts-cli. That migration was not without its difficulties, of which I could write a whole separate blog. Basically, no matter what I tried, I could not get node-fetch to import properly due to the differences between CommonJS and ECMAScript Modules which is a whole passionately debated problem of its own. After hours and hours of research and debugging, I stumbled upon this kind soul’s comment deep in a Github issue that solved my problem (not to mention introducing me to patch-package, which I don’t know how I ever lived without). With that problem solved, and my library functions once again working harmoniously with Sagemont Tax Apps, I breathed a sigh of relief. Until…

Until I saw Next.js had bumped up to version 13 with some cool new features. And in doing so, I found out that the framework for deploying Next.js to AWS, serverless-nextjs is also dead. So, there was the dilemma. Do we stay on Next.js with what’s working and rely on an unmaintained deployment method to continue to work? Of course not! The research began. Someone in the serverless-nextjs GitHub issue mentioned SST, aka Serverless Stack. I started reading. I liked what I saw. In fact, SST had set out to make it possible to do exactly what we were already doing with serverless-nextjs. Not only that, but SST is well maintained and even claimed support for NextJS 13 through open-nextjs.

Sound familiar? Precisely the deployment of Sagemont Tax Apps, just with a different serverless deployment framework. Great! I got to work.

First, I got the various scripts we run on AWS Lambda through cron scheduling to enhance platforms like Monday. That went well. Migrating from AWS CDK to SST was a breeze for the backend-only resources in Sagemont Tax Apps. In fact, SST is built on top of AWS CDK, whereas serverless-nextjs was not, and I was supplementing that framework’s Next.js deployment with AWS CDK. In fact, SST provides its own AWS CDK Constructs. At first, I was hesitant to switch from the AWS CDK constructs I already knew and loved to the SST-provided constructs. Now I can say that I’ve replaced all of my original constructs with SST’s versions. They’re simpler to use and provide pretty incredible features. How about the ability to live debug Lambdas running in AWS from your own machine with live-code reloading? You hope you don’t need that in production, but that’s a game changer when you do. SST’s Console is also an incredibly useful tool to quickly view your resources under SST’s management and interact with them. They even provide support for long-running jobs! AWS Lambda has a maximum run time of 15 minutes, but sometimes one needs to run a script on a daily basis that runs for 45 minutes like our daily data export from Monday for data analysis. All in all, SST is a massive upgrade over my previous approach and I’m excited to continue building with it.

Strictly speaking, SST did not yet support Next.js 13 within its main release when I finished this project last week. However, by perusing their fantastic Discord server and reading through various Github issues, I got Sagemont Tax Apps, the Next.js 13 portion, working using SST v2. Honestly, it just worked. Of course, as of 4 days ago (at the time of this writing), SST v2 has been officially released. They even have a great migration guide from v1 to v2. I wish I would’ve had that 7 days ago! Regardless, Sagemont Tax Apps is now up and running and fully deployed via SST.

And, ya know, all this intense research, changes, debugging, more changes, countless diet cokes, and all these collective hours invested into upgrading some frameworks got me thinking. As software developers, we get so excited about all the problems we can solve and how simple they are to solve. And usually, that stuff’s not hard. Business logic isn’t hard. Taking requirements and turning them into features isn’t hard (though understanding how to extract requirements is, that’s a whole other topic I may someday touch on). Every day I wake up excited about the impact I’m going to make on the business and our employee experience. Unfortunately, sometimes the hard stuff gets in the way.

What’s hard about software is all the little things that you hope to take for granted. That your deployments are working. That your tests are testing the right things. That when it comes time to make a change, it’ll be simple to deploy that change. That the idea you’ve had percolating will be done in hours instead of days or weeks because everything else that enables the development and delivery of that idea is already in place until it’s not! Then, you get halfway into a project to upgrade your frameworks and infrastructure with nothing to really show for it and more research to do. That’s when it’s so easy to get blocked and get behind on feature development. There’s nothing more daunting than changing out all the mechanics of a project when that project is working perfectly fine. That’s part of the reason why companies get saddled with tech debt. Sometimes, it just gets hard to make things better and give your developers the time it takes to figure things out and set the table for the next project. Sometimes, it’s easier to take the easy route.

Luckily, here at Sagemont Tax, we only exist to help our customers take the easy route. Internally, we understand that investments in infrastructure and a great software stack are crucial to delivering a great employee experience for software developers, which in turn greases the wheels of innovation and allows our employees to continue to deliver great experiences for our customers.

By the way, Sagemont Tax Tech is hiring. Come join us and build something great!

Written By:


Brent Rager

Chief Technology Officer
Brent Rager

Brent Rager

Chief Technology Officer
Brent Rager is Sagemont Tax’s Chief Technology Officer and lives in Fishers, IN. He is responsible for all things technology at the company including strategic planning for designing, improving, and optimizing company processes, full-stack software and infrastructure development, system administration and integration, data security, IT service support, and more. Brent was previously a software development manager at Genesys, a privately...
Learn More
Facebook LinkedIn

Our Sagemont Tax experts are proud members of...