The website vs webapp debate is at least as old as my career. And it keeps coming up. One camp says "React is too complex you don't need any of that", the other camp goes "I don't understand how you live like this". Both are right.
App and site are different worlds with different needs. I accidentally wrote a blog length comment about this in a thread on HackerNews. People liked it.
You don’t really have a complex app until you have 1 shared concept that 3 types of users look at differently.
— Swizec Teller (@Swizec) April 28, 2025
Same conceptual thing, many perspectives. All correct. All incompatible. All need to work together.
Your needs start simple, then they grow
I work on a site that was built without frameworks with just a sprinkle of jQuery on top of a traditional MVC framework.
It worked great but then the business grew and the software became bigger than what fits in 1 engineer’s head. We now have lots of issues that need fixing.
Your UX begins to tumble
A good example are pages that take 5 seconds to load because they have to do so much, then you submit a form, and the page reload takes 5 seconds to go through but there is no UI feedback so you press the button a few more times because maybe it didn’t work?
Then you get an error because the first action worked but the subsequent actions failed due to uniqueness constraints. Now as a user you’re confused: did you place the order or not? You got an error but the order also showed up in your history. Hmmm
Your domain modeling lacks boundaries
As engineers we have issues understanding what is and isn’t in scope. Will this javascript file you touched affect only the feature you wanted, or another 50 pages you didn’t even know about?
When you add a new thing in a template, how many N+1 issues across how many pages did you just cause? Where does the data even get loaded?? The query lives so far away from where you use the info that it’s really hard to track down. Etc
Fixing this is work
We started putting new things in React, especially the more interactive areas of the site. It’s pretty nice in comparison. Not perfect, but the framework pushing you to think in components helps a lot.
I’m slowly introducing this mentality to other parts but the framework really wants to fight you on that so it’s gonna take a while.
Doesn't this just change into same issues, new framework?
Yes and no!
TypeScript helps a lot – you get quick traceability of where things are used and squiggly lines, if you break a contract. Yes a statically typed MVC framework would get you this, but in my experience the apps that get into this mess also don't use types "because types add too much complexity" (likely true for that company stage).
Componentization brings the other piece – self-contained components that
- declare their own data dependencies (load their own data),
- bring their own isolated styling,
- and generally handle all their internal behavior.
Getting it right is not free
This takes some skill/experience to get right and yes you can totally pull it off with every toolstack if you're good enough. The benefit is having a stack that encourages you to think about interfaces and contracts between components and hiding the messy internals from the outside world.
So for example in Flask I'm encouraging this pattern of tiny composable views: A pattern for composable UI in Flask
Once you have these, you can then move them in and out of the page with some JavaScript and an Ajax call. HTMX does this afaik and it's also how we used to build PHP+Ajax apps for a brief moment 20 years ago before client-side rendering took over for various reasons (smaller payloads mattered back then as did sharing an API between web and mobile)
Guarantees help
Point is that an approach based on composability guarantees that
- components won't break each other,
- can be moved around,
- and can live side-by-side without worry.
The more your stack can guarantee this (as opposed to manual vigilance) the better. A traditional MVC framework is based on separation-by-technology / horizontal slices, not separation by domain / vertical slices.
This just smells like you're bad at code
To me that reeks of badly structured code, with bad abstraction layers, perhaps stuffing too much stuff into a single module or, if the language is still backward and doesn't have modules, a file
Yes and that’s normal. Big ball of mud is the world's most popular software architecture.
Well ... put it in "menu.js". Will it affect 50 other pages? No, it will affect the menu
MVC frameworks, used traditionally, don’t support this super well.
If you want some dynamic value in the menu supplied by the server, every view has to make sure it passes that value into the template layer. Change the menu, gotta go around changing every view to supply that new value.
Conclusion
It's about architectural complexity [name|]. And no matter what, domain modeling is hard.
And I think many if not most engineers have never worked on a complex app. Partially because the folks above them did a great job splitting code into small balls of mud
You don’t really have a complex app until you have 1 shared concept that 3 types of users look at differently.
— Swizec Teller (@Swizec) April 28, 2025
Same conceptual thing, many perspectives. All correct. All incompatible. All need to work together.
Cheers,
~Swizec
Continue reading about Why websites and webapps are different
Semantically similar articles hand-picked by GPT-4
- A pattern for composable UI in Flask
- Single page web apps: the worst of both worlds
- Don't neglect your upgrades
- Forget complicated code, focus on the system
- You can't fix the wrong abstraction
Learned something new?
Read more Software Engineering Lessons from Production
I write articles with real insight into the career and skills of a modern software engineer. "Raw and honest from the heart!" as one reader described them. Fueled by lessons learned over 20 years of building production code for side-projects, small businesses, and hyper growth startups. Both successful and not.
Subscribe below 👇
Software Engineering Lessons from Production
Join Swizec's Newsletter and get insightful emails 💌 on mindsets, tactics, and technical skills for your career. Real lessons from building production software. No bullshit.
"Man, love your simple writing! Yours is the only newsletter I open and only blog that I give a fuck to read & scroll till the end. And wow always take away lessons with me. Inspiring! And very relatable. 👌"
Have a burning question that you think I can answer? Hit me up on twitter and I'll do my best.
Who am I and who do I help? I'm Swizec Teller and I turn coders into engineers with "Raw and honest from the heart!" writing. No bullshit. Real insights into the career and skills of a modern software engineer.
Want to become a true senior engineer? Take ownership, have autonomy, and be a force multiplier on your team. The Senior Engineer Mindset ebook can help 👉 swizec.com/senior-mindset. These are the shifts in mindset that unlocked my career.
Curious about Serverless and the modern backend? Check out Serverless Handbook, for frontend engineers 👉 ServerlessHandbook.dev
Want to Stop copy pasting D3 examples and create data visualizations of your own? Learn how to build scalable dataviz React components your whole team can understand with React for Data Visualization
Want to get my best emails on JavaScript, React, Serverless, Fullstack Web, or Indie Hacking? Check out swizec.com/collections
Did someone amazing share this letter with you? Wonderful! You can sign up for my weekly letters for software engineers on their path to greatness, here: swizec.com/blog
Want to brush up on your modern JavaScript syntax? Check out my interactive cheatsheet: es6cheatsheet.com
By the way, just in case no one has told you it yet today: I love and appreciate you for who you are ❤️