> 1. You have to build your app twice. I don't have a team large enough to write it once in Python and again in JS or TS.
I have not found this to be true in almost 15 years of doing this[1]. Would be very curious to hear where you’ve found that you have to build the app twice.
Typically my approach has been to put Serious Business Logic on the server behind an API. This lets you contain all the important stuff in one place and ensure a ground truth for all your clients (web, mobile, BI, 3rd party integrations, async jobs, etc). You build this once. Then the client acts as a pretty interface for all this same data. Anything that smells like business logic, you put on the server and call an API. You also build this once because you’re not building any of it on the server.
Those secondary clients (BI, 3rd party integrations, async jobs, etc) are also where MPAs built on next+rpc or django and friends start falling apart. They’re not gonna load your webpage and parse the html or run the JS you sprinkled on top. You’re gonna have to build an API anyway. At that point you may as well make sure that all your clients talk to the same ground truth business logic so your API and your MPA turn into thin layers on top of core business services.
Congratz, now your MPA is essentially an SPA that runs on the server and you have a backend-for-frontend. You’re just making API calls on the server and not taking advantage of your visitor’s globally distributed compute and bandwidth. But it does make auth/secrets easier because you can mostly trust the server-client.
[1] Seriously, one of my earliest talks was on this newfangled thing called Backbone and how SPAs solve common problems we had with web tech back then (~2011). It’s in Slovenian though