I swear people must get so lost in the development of some sites that they don't realise how bad they are. Pathetic load times, unnecessary page animations, confusing UIs, hijacking scrolling.
The best thing is those fucking sites where after the page seems to be completely loaded suddenly new components or even worse: ads pop in, and you accidentally click on those instead of what you intended to click on.
Sounds like it’s by design. Payouts for clicks is way higher than impressions. Sneaky sneaky. Or, malicious payloads await on the other side.
My favorite is when a full react site loads up, doesn’t have error boundaries, hits some unimportant js exception, and the entire page that was fully rendered and ready to go just pops out of existence and you are looking at a white page. That doesn’t seem like forward progress at all.
Mozilla’s famous docs do this on my iPad pro rendering it utterly useless and honestly reflects badly on them, how can you claim to be an authority on documenting html/js when your site doesn’t even render?
People like to talk badly about w3schools but at least it manages the bear minimum of actually being able to render and display the information I’m looking for.
I think the next major change will be unified hybrid rendering. Render the initial view via SSR for speed, framework automatically injects more and more of the page transparently as user-driven events happen. All of this will be transparent and you only write the app once.
I think from the comments here: probably? I don't know anything about Svelte, so I can't really say, but you're the third person I've seen say "this sounds like Svelte", so I'm inclined to think you're all right :)
So has it taken off / is it taking off? If not, why not? Or more to the point of my original comment: Why is something like this just now taking off? Has something new enabled this in the last few years?
It's not a new idea was my point in my comment, so I'm curious why the idea never seemed to take off in the past, and why it might be poised to now.
So, I was trying to do this literally a decade ago (as in, I remember it being 2013 when I started trying to make an angularjs site work this way). I haven't been doing front-end or "full stack" for awhile, so I'm a bit out of the loop. Why has this seemingly failed to progress in the last decade?
Most of the more modern Javascript SSR frameworks support hybrid in some capacity (Remix, Next, Svelte). I can't speak for Angular as I've never used it.
Oh, I didn't mean to focus the discussion on angularjs; that "angularjs" that I was using was essentially a totally different and now-deprecated framework from today's angular. I just meant it as an example of why I don't see this as an up-and-coming idea, but rather something that has been the clear best path for a very long time, but doesn't seem to have taken off.
I don't know enough about any of the frameworks you mentioned to evaluate whether the "hybrid in some capacity" actually does mean this approach has become widely used, but I guess from my experience of using the web, it doesn't seem like it is common, it seems like most applications are still sending a skeleton and then filling the data in client-side, rather than rendering the initial page load server-side.
This is already here and in use. See Next.js using React.js for example. Server-side rendering out of the box and small next needed pieces are loaded continuously when they are needed.
Nice! Anecdotally this still doesn't seem to be the dominant way that web apps I use are implemented. Is this just taking awhile to get mindshare, or are there some drawbacks keeping most people from using it?
Because it adds a lot of complexity for the small benefit of shorter initial load times. There are many issues, for example you need to make sure that all your front end code runs both in the browser and in node. You need to mark parts of your UI to not server render, you need to be aware of the timing between the site being loaded and hydration being finished (a text input might have some value prefilled from the server and may be changed by the user before hydration finishes). Just from the top of my head.
My experience is that most of the time it’s better to make your public facing site fully SSR and then make the actual app fully client side rendered. You usually don’t need that much interactivity for your public site and your app users don’t mind a few seconds startup time. You also usually don’t need SEO for your app because it’s behind authentication anyway.
This is what react server components is: the component tree renders on the server and is sent over a chunked http connection, gradually filling the page. The code is not sent to the client because events that necessitate a rerender go back to the server in a new request.
I have been using Blazor for the past year and I've got to say it's pretty incredible. It has some downsides and .NET 8 with Blazor United is going to be a very welcome change, but I can have my cake and eat it too. I finally get to use components, write some client-side stuff in C#, and I don't have to touch a lick of JavaScript or TypeScript. I get how irritating it is for people to beat the "JS IS BAD" drum, but man, it's nice to use proper typing in a language that has some pretty damn good syntax.
Isn't "Thiel Truth" just a euphemism for a strongly-held opinion? Not sure why this banal concept has to be attributed to some venture capitalist. Seems like clickbait.
That aside, just use whatever fits best for the task at hand. If server-side rendering works better for you, use that. If client-side rendering is preferable, do that instead. Or a mix of the two. No need to be dogmatic about it.
I think they mean, if it isn't an application but should just be a website. Many things are designed as applications with a lot of behavior, when really they are just documents that would be better structured as a hypertext "site" with linked pages of content.
I really think this should be the first question on a project: Should this be a website or an application? I think the answer to a huge number of technical questions is dependent on the answer to this product question. And it seems like too few people are asking it, and are instead diving straight into making an application (whether web and native).
Personally, I'd prefer website to apps. Most apps don't have good reason to be an app over a website other than to better track users (like reddit's app for example). Also, I can easily visit a website from any web browser, but apps need to be installed first.
First I’ve heard of this interview question but if anyone is wondering here is a guaranteed way to fail a job interview with Thiel by answering the question thusly:
Beanie Babies would make a rather poor unit of account. As at any given time, two of the same model Beanie Baby can be worth two very different amounts in trade based on their condition. Whereas a dollar bill does not matter what its condition is (at least within a reasonable range), it is still worth a dollar. Also, two different models of Beanie Babies will vary in value with relation to each other, whereas a one dollar bill will generally always be worth 1/100th of a 100 dollar bill.
I disagree with that definition of money. I don't think it actually defines what money is or what it does. I think that if you want to think of money in terms of "value" that rather than a "store" of value, it is a "record" of value.
If you want to think of it as a unit of account, it has to be a state unit of account in order to actually function as money.
And finally I think that the function of money as a medium of exchange is actually a side effect; that is to say that money is the most liquid asset because it is created by an obligation in common to all citizens of a sovereign entity. As such, it is the most likely medium of exchange because it is universally accepted.
However, anything can be a medium of exchange. Hot rocks can be used to heat a room, but you wouldn't call a pile of hot rocks a heater. In the same way, virtually anything can be a medium of exchange, but money (by virtue of being created by the imposition of a tax liability) is the most effective medium of exchange.
My definition of money is: a credit that can be used to extinguish a tax liability imposed by a sovereign. Everything else is a commodity.
Which ones? Every crypto that gets any amount of usage immediately hits up against deliberate scaling limits in the consensus mechanism[0] and stops being a useful medium of exchange. Cryptocurrency also has extreme speculative risks, which means that it's useless as a unit of account or a store of value.
Fiat currencies don't have these problems[1]. Because they are instituted by a government that forces people to use it, they have a large volume of economic activity which makes it harder for the currency to swing dramatically in value. The reason why Bitcoin can fluctuate so wildly is because few actually use it like a currency, so there's nothing to buffer against market manipulators and forex speculators.
[0] Because crypto needs global consensus over every satoshi in the system, all transactions need to be widely propagated to all full nodes, which imposes strict limits on how much transaction data can be processed at once. If the limits are too high then only large institutions can run full nodes which is centralizing.
Of course, literally everything else in crypto is centralizing, because centralization is the gravitational force of economics.
They're charged by the entity that issues the currency (the network/the miners), for the act of using the currency, which I think could reasonably be classified as a form of tax.
They could be considered a transaction tax and/or payment processing fee. But they are not the reason people would be willing to accept a token in exchange for some real resource like labour, because unless you’re already using that token you are not obliged to pay for anything using that token.
Demand for that token is thus entirely speculative and could evaporate at any time. Since there is no issuing authority that guarantees to accept the token in order to exonerate some obligation we have in common the last person holding the token simply loses the game.
Yeah in practice, it's almost certainly important for the answer to be something that most people don't believe but which Peter Thiel does believe. It's just the typical "are you like me?" interview. If the interviewer is a conformist, they are looking for a conformist, if they are a contrarian, they are looking for a contrarian. Same as it ever was.
I’ve never met the man, but in my experience with more locally famous/infamous people with roughly similar reputations is that there are few things they love more than a really strong intellectual sparring partner.
Of course many boring posters on HN will never accept that because their models of the world only allow for 1 dimensional villains on the other side of any ideological disagreements.
OK, my model of Thiel would say: are you offering me a thesis from bestselling author David Graeber, or is this a view that actually very few people hold which you're disguising as a popular one for some reason?
(i.e. he'd reject this as boringly conventional before it got to the level of does it make sense? I've only read a little bit of Thiel, like 2-3 blog posts worth.)
I mean it's not really as hominem is it? I'm not arguing the point at all. I just mean that invoking a controversial like Thiel for something as reasonable as discussing the merits of server side rendering is a very odd choice.
"Title: A Stalin-inspired Look at Webfarm Management
Body: Apocryphally, Stalin once said that quantity has a quality all its own. As such, our hosting system involves an absolutely bonkers number of servers."
Whenever I encounter a server-side rendered app which _doesn't_ work well, and I make a cursory examination of why, I usually find it's down to poor choices.
Ads causing reflow, embedding of other elements (off-site) with poor performance, the Cambrian explosion of trackers and other cancerous marketing-related cruft, labyrinthine page layouts because someone wanted a pixel-perfect visual. All things which are not the core app itself. This leads me to suspect that most apps would work just fine with a few easily anticipated exceptions.
It also usually means an app can be MVP'd a lot faster with less resource and fewer vertical skillsets
Large structural changes can often then be made early in the project by a single person or alternate concepts quickly prototyped when it's effectively a monolith -- you don't as quickly get locked into "we'll just have to live with that now"
I'm not against introducing client-side once the final functional form is reached if justifiable gains somewhere -- but from day-one it's usually just a headwind on a project of any complexity
> What important truth do very few people agree with you on?
Seems like answering with SSR would fail a Thiel interview for two reasons:
1. It's not important (in the grand scheme of things)
2. It's not a view that very few people hold. SSR was the standard way to do things for a couple of decades up until frameworks like React, and React itself now implements SSR, doesn't it?
Thiel uses this question to try and determine if someone is or can be a free thinker, someone who can discern something to be true even in the face of significant social opposition. That's valuable if you're an investor looking for overlooked opportunities, or an entrepreneur trying to find an edge in a highly competitive market. But there is no taboo or significant social opposition to SSR webapps, and bluntly, no edge to be found there.
SRS is more secure because it doesn’t send down any links a role can’t see including even the link to get-based access from the account. It’s hard to attack a surface that is small.
It has to do with the size of the attack surface. in order for things to be client side driven gui elements need to be loaded for different role types. Those elements are often exposed If not directly then by showing which APIs are used to Authorize access to admin areas. That’s the whole point of rendering on the client. To load some Little div you might have an API call that when access by different role types will respond differently. With Server side rendering you never see the different API points for each role type As they get their own.
Why would the elements HAVE to be loaded for different roles? You're talking as if every single client-side app approaches authorization and authentication the same way and that's just not true.
There's no attack surface here at all, the only issue with most client-side apps and interaction with server comes from CORS and devs copypasting solutions from SO to get rid of the warning, thus creating the attack surface.
The choices related to displaying appropriate elements based on current user's role that's tied to entire logic of the app has literally zero to do with security.
Because the whole point of client, side rendering is to not have session management on the server side so that it uses less bandwidth on the server provider.. that’s why you have JWTs and stuff like that.
Architecturally when you have a session management system, where state is able to be maintained per user usually up by the same thread on the same physical server. that’s going to be more secure than a horizontally structured infinitely scalable system. But there’s always trade-off between security and usability/performance
> Because the whole point of client, side rendering is to not have session management on the server side so that it uses less bandwidth on the server provider
No, the whole point of client-side rendering is to apply parasitic computing and offload the server by having the client perform work it can thus saving the bandwith and compute power.
Next benefit is application that's "snappy" and works well, which is what almost never happens sadly.
> that’s why you have JWTs and stuff like that.
No, you don't have JWT and "stuff like that" because of this. JWT is for offloading databases so you don't have to talk to a DB on every request since you can verify the token via signature check and thus implement distributed services that don't have to talk to central authority to authorize a request.
> where state is able to be maintained per user usually up by the same thread on the same physical server
And now you're trying to sound smart by adding servers and "threads". I've a feeling you're pulling my leg right now so I'll excuse myself since you started spouting absolute nonsense.
What are you talking about? It’s well-known that Apache has a philosophy that every connection should be serviced by its own thread, whereas NGINX is an event driven architecture which means you have a thread-pool: think of it this way it’s like having the same dedicated waiter at a restaurant versus having the first available waiter come service your table or refill your drink, even if that waiter is different each time.
Concerning JWT, I think we were talking past each other as I was referring to a session-less Authentication scheme, which is more or less what you describe.
Finally, there’s no reason why the server can’t render JavaScript as well other parts of the page. In effect, if the server wanted to, it could render of a reactive version or an angular version depending on a variable. Can the client do that?
SSR has more potential for security issues because you're often rendering some set of data from your database, which may come from a user, out to a browser which will then parse and execute code based on that rendering.
You have to be sure your data going into the database doesn't have XSS escapes or your rendering of untrustworthy data doesn't have such XSS escapes.
Which is why you shouldn't roll your own SSR unless you are fully aware of this.
SPA doesn't have this problem as it will generally insert DB data into the DOM as text, no possibility of escape or execution by potentially malicious database entries. Not that you can't have issues in an SPA, but you have to do work to bring them about.
This isn't a difference between SSR and SPA, it's a difference between using a modern framework and rolling your own.
If I get a user-provided string from the server as a JSON property and set it via `.innerHTML =`, I have an XSS vulnerability. If I use React's JSX string interpolation, I don't.
If I get a user-provided string from a database and inject it with a PHP `<?= ?>` tag directly, I have an XSS vulnerability. If I use Laravel with Blade templates [0], I don't.
You're not saved from XSS by virtue of using JavaScript to render your code, you're saved from XSS by using a framework that escapes everything by default. Whether that framework builds the escaped HTML on the client or the server is immaterial.
You have to explicitly use .innerHTML. As I said, "do work", not that it is impossible. No SPA frameworks do this by default. The default is $DOMElement.textContent = value, which has no escape potential.
Everything rendered by the server has this potential as it must be deserialized by the browser.
No, but I've definitely seen bespoke, hand-rolled frontend code do it. You can't select SPA frameworks as representative of frontend rendering but look only at hand-rolled PHP from 2002 for backend rendering.
No major SSR framework is XSS-vulnerable by default. Whether you're using Rails, Laravel, Spring, ASP.NET, Phoenix, or whatever, every template engine escapes your strings unless you opt-in with something like Rails's `html_safe`, and they have for over a decade. Unless you've built your own SSR framework by hand with raw string interpolation, the "easy" way to do things is also the right way, just as it is in React.
Except what happens when react as the vulnerability you get attacked with everybody else with zero days… security through obscurity should be incorporated into any well multilayer defense. Make it not worth their time
We’re talking about where dynamic variables get populated either on the client side or the browser side. If you put invalid input, it doesn’t matter what side it gets surrendered on. Input validation and rendering are separate issues
There is often opposition - if the company I work for asks "what should we build the next app on?", React is the default answer that doesn't need convincing anyone, while SSR is much harder to sell (even when it makes complete sense).
All this noise around "back to the roots" template rendering seems to ignore the elephant in the room that FE devs DON'T want to work with jinja2, django templates and all this jazz as it is perceived as a devaluation of the role + they need to learn specific syntaxes instead of having a "one size fits all" approach like with js frameworks.
As a frontend dev I can give you a few more reasons why I don't want to go back to writing templates as part of some backend framework:
JavaScript is eventually needed for any non-trivial app. JS without a build system/dependency management is a maintenance nightmare. JS without linting, TypeScript, module syntax and unit tests is a maintenance nightmare.
Reuse of components is much easier and more testable with framework abstractions (compare a react/vue/svelte component to e.g. a laravel blade component).
Strict separation of CSS, HTML and JS means things like class names drift. With a JS build system you can easily introduce tooling to combat this (auto-removal of unused styles, enforcing that all classes are used, linting for CSS code, etc).
I just can't imagine building an app of more than a few thousand lines without a framework and frontend build tooling. I would end up needing to reinvent these tools myself to ensure code quality as the project grows. I'm not saying it's impossible to add these features into, say, a Django or Rails app, just that it's more work for a worse outcome.
Many apps with moderate interactivity don’t need thousands of lines of JavaScript. And using a backend framework for templating is not mutually exclusive to using a JS build system for helping transpile files and purge CSS and such.
> Many apps with moderate interactivity don’t need thousands of lines of JavaScript.
I mean, maybe? Depends what you mean by "many". I'm certainly not advocating for adding JS & frameworks where interactivity is not needed, and as I mentioned, for less than a couple thousand lines, an SPA framework is almost definitely the wrong choice. But my experience in the last 10 years is that very few projects do not grow to the point of requiring quite a bit of JS for interactivity. Async requests, complex client-side form validation, comboboxes, dynamic modals/content previews, showing/hiding long content, 3rd party integrations... these sorts of requirements are in nearly every app these days. And the HTML/CSS only solutions are just not good enough yet, unfortunately.
> And using a backend framework for templating is not mutually exclusive to using a JS build system for helping transpile files and purge CSS and such.
Sure, but at this point, why are you avoiding introducing a JS framework? All that stuff is built in to most JS frameworks (but not backend frameworks). You could piece it together yourself... but for what benefit?
This is why I am bullish on React Server Components. With a framework that supports it I can choose where client- or server-rendering is most appropriate but keep organization and expressive benefits of React, TypeScript, and TSX.
Related, the junior FE devs want our web app to be a SPA because they think it’s the only idiomatic way to write reusable components (think a JSX-written React component). Often they’ve never used anything else (so like TFA mentioned, for them it’s not an open choice).
I hate that my job these days has to involve counteracting this notion, probably looking like some weird Luddite in the process, for simply highlighting the same points from TFA.
Speaking as a primarily BE dev with a preference for static typing - what I love about React is that TSX makes writing view code much easier. I get type safety to check that I'm passing in all parameters I'm using, type checking + the editor's autocomplete helps with HTML and CSS that I'm not as familiar with, and TSX being a relatively light sugar over Typescript provides more flexibility/power/ease-of-use than any templating language I've worked with. Go templates and ASP.NET .aspx templates (I think those are for Web Forms, specifically?) are much more annoying to work with.
My thoughts exactly. Although I don't see it as a devaluation. It's just not that convinient. And yes I admit, after years of working with a clear component system it is hard to go back to templates. They are just not it...
I would really appreciate some advice, which template engine is good enough and how to organize with it something similar to how we write components in all these FE frameworks.
Sure, but the advantage is that if you can write your rendering logic once and have it run both server-side and client-side, you've saved a ton of work.
I honestly wonder if everything that is a best practice on the backend and frontend these days is a net negative compared to "Write your own PHP or Python code which outputs your own HTML+CSS+JS".
Especially for indiemakers and startups by technical founders.
All the frameworks add so much complexity and confusion.
And I have seen several startups fail because when the developer was confronted with breaking changes of their framework, they said "Ok, that's enough. I'm not going to plow through this".
The simple "PHP or Python talks to the DB and outputs an HTML interface" type startups have a pretty good success ratio on the other hand.
I’ve rolled my own mvc framework before, In php even! This was years ago when CakePHP was the new hotness and Laravel didn’t exist. Take it from someone who had your mentality and set off to make a tiny and no bs mvc that just gets the job done, the amount of work these frameworks are doing for you (backend frameworks) that you don’t consider, is why you should run a framework.
You don’t want to deal with processing a raw http request from the web server. You don’t want to split headers. You don’t want to sanitize input params, deal with character encoding, content types, gzipping, cache control, etags, basic authentication, flushing headers, chunking bodies, file streaming, tcp sockets, slow client avoidance, and probably 1000 other things I can’t recall.
No matter how unnecessarily complex you think a http framework might be, I assure you, it’s saving you from a mountain of already solved by people smarter than you or I complexity.
Well, I do all that and it works just fine for me.
All my projects are 100% my own code down to the core. No frameworks, nothing. There might be some traces of jquery in there from when browsers were more unreliable. I don't even use that these days.
To get to know those frameworks, I built some projects with Symfony, Laravel, Django and some others. But it didn't stick. They are too aggressive in their "do it my way, don't worry what happens behind the scenes, let me do the magic" approach. I had the best impression of Django. That is the only one I might give another try.
How’s your vulnerability reporting process and how much experience do you have interpreting complicated pen tester bug reports about some buffer overflow zero day in your homebrew query string parser?
Huge difference between working fine, and working right. The security implications of rolling your own, is why I say “you don’t want to…”
Also, none of that code has anything to do with the product you’re actually trying to build. Imo it’s additional maintaining, tech debt, attack surface, and it’s a solved problem by a large community and has more knowledge from the security community baked in, and more eyes finding and plugging holes.
In the aughts, when everyone was rolling their own framework, security and maintenance were a nightmare. It's undeniable. We traded one problem for another, however, and we've gone too far. I think the question at hand is which is more secure/maintainable: 10kb of custom utilities or 100mb of mystery-meat modules that, let's face it, will never be reviewed. It's not a simple answer.
Smaller file sizes or less LOC is not inherently safer than larger sizes or more LOC. if you’re building web apps, you’re more than likely reaching for a handful of packages, and so are millions of other people, and so are multi billion dollar companies, companies with staff who’s job it is to do supply chain security, PCI compliance auditing, security assessments, who hire pen testing firms, and some even write browsers and can sway the direction of our entire industry and the internet as a whole. Countless static code analysis is ran on the millions of CI jobs a day on builds that pull in the package, etc. If you’re using popular and maintained open source packages, people are looking at them. Shy away from no name packages with no usage unless you personally look at the code. That’s my take on it. I tend to trust the open source community to all be working towards the shared goal of well crafted and secure code for the world to use and benefit from
I’ve yet to find a framework that I really like. Ironically, most Python frameworks feel like they force way more coupling on your code than necessary, which is awful considering they are a dynamically typed language. So it feels like the worst of all worlds: Python performance, high coupling to something you don’t control, and dynamic typing.
I understand why these are designed that way, but also don’t enjoy using them. Frameworks can feel very narcissistic in that sense, all the code is about them, despite their promise that you’ll focus on your domain more.
I need to play with some of the Kotlin web libraries more, such as ktor or Javalin. There has to be something better out there.
Django is a super heavy framework that includes most anything you'd ever want. There's a ton to learn. Have you tried lighter-weight ones like Flask? I much prefer a lightweight web framework with an easy-to-use ORM/ODM.
Also, even though you don't use frameworks, I assume you use various libraries to handle web requests and such, right?
As for libraries: PHP has great http and html support build in already. Python is a bit tricky in this regard. That's why I would give Django another try for new web projects. But I also had success just rolling my own http/html code in Python.
Because it is, by far, much larger project? Django has 551k LoC in 31933 commits, Flask has 27k LoC in 5156 commits. Django philosophy is "be opinioated, and bundle everything necessary for developers". Flask philosophy is "do just one thing and just be a good HTTP server, let users pick a solution to all the other problems". Django is a full-blown framework, whereas flask is almost a library. Both approaches are OK, but from your previous message (GP) you prefer lightweight and magic-less frameworks (and Django relies on some conventions to do its magic).
>One thing that keeps me from investigating Flask further is that Django seems to be way more popular:
Both Django and Flask are way more popular that what you're doing (writing everyting yourself. By the way does it mean you write your own HTTP server too?), so I don't know why that stops you. Flask is not going anywhere.
>Me and other devs maintain this repo which shows how to get from a fresh Debian install to a running web app via different frameworks:
Interesting project, thanks for sharing! But that's a bit random - what was your intention when linking it? Also I can't help but notice that the flask example there has three third-party dependencies other than flask (flask-sqlalchemy, flask-login and wtforms). Since you like rolling your own solutions, maybe you would prefer Flask without such libraries? (I personally don't use flask-login and wtforms, and only sometimes use flask-sqlalchemy - I usually use standard sqlalchemy, my custom ORM, or just write SQL directly for simpler projects).
I don't mind so much about the LOC of a framework. If there is stuff in there that I don't use and that does not get in the way of me doing things, thats not that much of a problem.
As for Flask not going anywhere - well, all projects go down the drain at some point. Just 10 years ago, the Zend framework was more popular than Django and Flask combined:
> You don’t want to deal with processing a raw http request from the web server. You don’t want to split headers. You don’t want to sanitize input params, deal with character encoding, content types, gzipping, cache control, etags, basic authentication, flushing headers, chunking bodies, file streaming, tcp sockets, slow client avoidance, and probably 1000 other things I can’t recall.
The Golang stdlib does all this for you, no framework needed :)
I honestly think Golang SSR with html templates + a sprinkling of Javascript to enhance is an extremely pragmatic way to go.
You build your entire service into a single binary (assets included with go:embed).
You shed the complexity of the framework AND the web server AND deployment in addition to React etc.
Golang is in a special class on its own. Write some handler functions and pass around a context struct and call it a day. I wish every stdlib took care of all that stuff :)
Do they have a good success ratio? Do you have some data to back that assertion up where you've analyzed startup success by whether they used SSR or CSR?
My own personal experience has been working at a large enterprise SSR app that ultimately failed to keep pace with increasing competition (but certainly achieved some success with basic SSR forms in the early 00s), then later worked for a team that had a $500M exit for which the CSR app and backend Node.js API was built with a minimal team size of just a few dozen devs.
I'd be pretty surprised if someone had gone to the effort to organize startups by SSR and CSR and then tried to make an empirical point with it. Just seems like a fool's errand to me, too much noise to get a useful signal.
I have no doubt someone will bring up levelsio (hey Peter!) and his slew of wildly successful sites SSR sites powered by JQuery and PHP, but I've always felt his stack choice was secondary to his ability to market and quickly ship.
It's a bit of a truism, but I've really come to accept these days that the best stack is whichever one your team is most productive with.
Mostly because it lowers the bar for execution. And that is not just a one time thing: it affects how fast you can on-board, ship new code, and refactor.
And that iteration speed is key for chasing down product market fit, which is way more dangerous to a company than suboptimal tech.
People get so intimidated by these huge frameworks and get FOMO, that they never try to build something from scratch.
React seems simple, but if you tried to understand what is going on under the hood it would take you months.
Simple should be: can you trace through all the code yourself. Like Backbone.js for example.
Plus, there is already so much rendering complexity under the hood in browser engines. The DOM and CSS are already incredible abstractions available for you to use.
I really don't get what is so bad about just having some object to manage a dom element's rendering.
Create a single relational source of truth for your data. Then create some view models that listen to this source of truth. Then make your objects listen to these view models.
This vdom diffing stuff is so overated.
If you have a list of items, and a new item is inserted, I can just insert that directly into the dom. If I render a different entity and it uses mostly the same dom elements, it's really not that hard to tell say: here are some new props, compare them with your old ones, and do what you think is best. React promises this for the entire app but its all magic. I want control of my rendering so I can make things fast. Debugging perf issues in React is insane. Good luck debugging anything.
> You will need a backend anyway. It'll need to expose data to users. Exposing it as HTML is no harder than doing it via JSON or GraphQL
Sure, if your "app" is just buttons and UI that interacts with a backend DB, I agree. However, many PWAs and native apps do lots of heavy lifting on the client side, and loading the backend with that is not cheap at all!
exactly, exposing the backend with HTML is harder, if that is supposed to mean the complete interface which includes CSS and javascript. without interface it would just be XML, at which point JSON would be the better choice.
even more, many backends can be simple CRUD. i reuse my backend for all websites and haven't had to do any custom backend coding in years. so my current backend cost is zero, because i can do it all in the frontend.
Yeah, I don't get how it'd be cheaper at all. Yes you need a backend anyway, but unless you're not paying for usage and have spare CPU cycles and bandwidth available, it's not cheaper. It's cheaper to send your frontend html+js and let the browser cache it so it's only sent once, and let the frontend pull only the data it needs to render the html. The backend isn't having to process a template, or resend similar html constantly to the frontend since most of that likely cannot be cached.
Lot of bashing of this idea, not sure why. The entire industry has shifted from "web developer" to frontend/backend developers. What used to be a web developer is now called full stack.
It seems like a big deal to me and the entire shift is an indicator of how much the IT community is behind front end clients talking to a separate back end. Server side rendering is no longer considered normal. Server site rendering now means something entirely different. It is about running your frontend code on the back end, So you still have the separation, but instead running it on the same machine. Now the same ui code has to be compatible with two different run times. This is much, much more complex than traditional server side rendering.
I'm glad we now have things like single page apps and client site interactive applications, because some apps were really not possible with server side rendering unless with a lot of Jquery hackery that quickly becomes unmaintainable...
However, I do think that front end technologies are overused, so I agree with the author, And I also think this is objectively a contrarian opinion, considering my initial point.
> I'm glad we now have things like single page apps and client site interactive applications, because some apps were really not possible with server side rendering
And maybe server side rendering is just the right answer for websites which are not the two you mentioned.
I wouldn't say server side rendering is a "Thiel Truth," because it's a thing that is already popular and uncontroversial and agreed upon by millions.
There is an echo chamber where this happened:
* Facing massive datacenter costs, Google and Meta realized that if they could hand off rendering to the client, they could have smaller datacenters and save a lot of money. Things like React and Angular were born. Other companies with large datacenter costs followed suit, many monies were saved.
* This is when things started to get a little crazy. VCs started pushing heavy client-side SPA this and that because if anyone knows how to cargo cult, it's VCs. Devs started pushing it because it was a hard way to do things and if anything improves your salary, it's being involved with the hard bleeding edge stuff. Also inventing another JS framework turned out to be a great way to pad your resume. Design and UX people realized this was a whole new can of worms they could get paid to open, and dug right in. (In all cases note that the original point, saving money on compute at massive scale, was totally lost, and people just made up new reasons.)
* Outside of this echo chamber which is utterly convinced it's filled with the smartest people in tech, life has actually gone on pretty normally for the rest of us, we're still doing stuff on the server whenever we can, and caching the hell out of everything we can, and being judicious with fancy client side frosting because complexity is generally the enemy. That said, it's definitely true that an entire generation of young web developers has been lost to madness because young web developers also like to cargo cult a lot, and the damage will take years to repair.
> Facing massive datacenter costs, ...Other companies with large datacenter costs followed suit, many monies were saved.
I can't think of anyone who doesn't want to save money on servers. Seems like a pretty good general win to me for using the client.
> complexity is generally the enemy
Agreed. But minimizing complexity doesn't require not using a heavy client. You can go fully the other way and make the backend a relatively simple permissions and validation mask on top of a database and let the front end hold all the relevant state.
Use client side rendering and have simplicity too.
I will admit that an SPA turns out to be easier to mess up and design really poorly, but I believe that this is a tooling maturity issue rather than fundamental to the platform. SSR frameworks have had over a decade longer to mature.
Interesting take. Haven't heard the argument before that it saves server costs. Not convinced that this is the case, but perhaps, for a google.
Reflecting, I suppose that businesses relying on Php/Laravel or Ruby are probably still enjoying simple SSR development. I've personally transitioned to Java and then .NET, and haven't seen SSR since. Which corner of software are you in, where you see SSR still being dominant?
For one thing, I don't think the motivation of Google and Meta was datacenter costs, though I could be wrong about that.
But it's not that "VCs were pushing client-side SPA", it's that lots of the companies that wanted to build applications, found that they had a set of problems that was best solved by things like Angular. The state of the art before that for highly interactive client-side apps was JQuery, and for a few years, things like Backbone.
Angular solved a real problem - people wanted to build more complex and more interactive client applications in a browser, but just using regular JS (or JS with Jquery) led to really messy applications and was very hard on development.
You can try and handwave all that away as an echochamber, but I think the majority of the industry moved to SPA frameworks as solutions for building client-side apps.
> I don't think the motivation of Google and Meta was datacenter costs, though I could be wrong about that.
Have you forgotten that these are profit-maximizing companies? Why do you think they do anything? To maximize profits. That is always the answer. If it doesn't maximize profits it's a mistake and they will back away from it.
So for example Facebook either thought that React would increase sales, or reduce costs, otherwise they wouldn't have created it. React hasn't moved the sales needle for them (why would it - they are an advertising company - React has precious little to do with selling more advertising). Ergo it was created to reduce costs. The cost benefit of moving all that compute out to the client is easy to demonstrate and significant for a company of that size.
Is there any evidence, even anecdotally, that reducing datacenter costs had any significant relevance to the development and rise in popularity of single-page apps and JavaScript UI libraries like React and Angular?
My own memory of the history of the web is that early web sites with a lot of client-side interactivity benefited greatly from the huge leap in interactivity, and came out several years before JavaScript libraries were widely available for ordinary developers to build web sites with similar functionality. (I'm not counting arguably "non-web" technologies like Flash and Java applets.) The earliest such web sites I can remember are e-mail, calendar, and mapping apps.
That doesn't match what I saw. What I saw was people hammering on latency because of its effect on conversion and other forms of engagement, and believing that the best way to control latency when consumers often had slow, unreliable connections was to avoid round trips and/or push them into the background. I.e., avoid page loads. SPAs allowed developers (at a cost, granted) to control how a web page's functionality degraded when dealing with slow or spotty connections, and that was seen as having immense ROI for anything consumer-facing.
Naturally after years of investment in building consumer-facing sites like this, the skills and tools became ubiquitous and arguably overused.
The reason client-side rendering is so popular (IME) is that it creates a clear separation between frontend and backend devs. You can use separate repositories, languages, deployment flows/cadences, code review, etc, with an API as your connection point (and the fact that you get an API by default with CSR is also nice).
I don't think CSR is going anywhere, mainly thanks to Conway's Law.
The same argument could be used for splitting backend to multiple services, or even micro services. Frontend/backend separation seems pretty arbitrary.
If anything, I'd say that with server rendering, separating different modules is easier. You want to rewrite that page? No problems. With client-side rendering there's usually expectation of some monolith project using the single framework.
You can (and probably will) have multiple different frontends with website vs app. If you have a clean API for the backend, then you have one set of calls which can be made from multiple different user interfaces
> If anything, I'd say that with server rendering, separating different modules is easier. You want to rewrite that page? No problems.
It also gets you vastly more choice in language/tooling/etc, even allowing a mixture of different ones, which is what attracts me to SSR. Of course this may change in the future once WebAssembly has had most of the DOM interop overhead optimized away, bringing this freedom to CSR.
Maybe you're right that people find it easier to think that way, but it seems rather illogical to me.
The very first step in creating this separation is to define an API that is implemented and operated by backend devs and used by frontend devs. Once you have done that, you have achieved all the clarity that is necessary or possible.
Whether or not some parts of the frontend are executed on the server-side shouldn't matter for the question of who has responsibility for what.
Perhaps it's more about the ease of hiring for different skillsets. If frontend is synonymous with client-side and backend is synonymous with server-side, it makes life easier for HR and recruiters.
There's definitely at least some truth to this. And even when working on both frontend and backend (on a small team), I find it useful to have a clear separation between client-side code and server-side code, with a well-defined boundary between them. This might be shaped by my experience with ASP.NET and .aspx templates, though; I struggled to understand when and how the client-side code would call the backend to send input or get updated data.
First and foremost I tried to have the whole flow of UI and clicks be nothing more than request after request. Compared to modern javascript frameworks it might not be as smooth, but it is super quick and works for my use case. Of course I use a little javascript here and there, but the javascript is not making server calls (except for my visitor statistics module).
Specifically, it depends on context. How big is the app? How many people are involved in building it?
As with many things, separation of front and back ends grew out of web-scale companies and products. If you're buiding Facebook or Spotify or Gmail, then you need a way to partition your app - because you need to partition your people. Humans need structure, we don't deal well with single teams of multiple hundreds.
Many apps don't fit that model. Lots of apps - e.g. business internal apps - might target at most small 100s of users and justify a dev team of < 10. In that world, separation of front end and back end devs & stacks is a disadvantage. Single language, single build apps mean less technical surface for the team to cover. Which means each person can more flexibly turn their hand to the requirements. Most people can do most things end to end. Features are business-driven and end to end. A single PR can deliver a meaningful piece of user-accessible value. There's no unionised demarcation.
None of which says "separate UI & back end is universally wrong". But it's not universally right either. As is so often the case, it degenerates into a discussion that is technical and absolute when the underlying forces are organisational and relative.
> The reason client-side rendering is so popular (IME) is that it creates a clear separation between frontend and backend devs. You can use separate repositories, languages, deployment flows/cadences, code review, etc, with an API as your connection point.
You say this as if it is necessarily good, but I disagree and would even say it's actually a hindrance for many teams. It often adds inefficiences, increases costs and makes planning and collaboration more difficult.
> the fact that you get an API by default with CSR is also nice
The vast majority of applications don't need an API.
I saw the effect of silently forcing hard-core SSR on my team over the last few years. My trick was to not give anyone any say in the matter. I built a product vertical that demonstrates how it is possible to handle not just the happy path, but also the unhappy edge cases.
It is one thing to push an abstract policy/principle. It is another to hand someone a live, working implementation of a policy and request that they keep moving down the indicated path.
I don't think SSR is a Thiel Truth. I think leadership is. If you want to see more SSR in the world around you, you have to build more SSR experiences and teams around them.
Letting a room full of arbitrary developers sit around a conf call and come up with "the tech stack" is how you wind up in a hurricane of bullshit most of the time. At some point someone needs to ask the question "are we here to make money or have fun?" which should quickly highlight your ideal candidates for CTO/dictator.
A good reference in this space is Rich Harris' talk on "transitional" web apps: https://www.youtube.com/watch?v=860d8usGC0o ("Have Single-Page Apps Ruined the Web? | Transitional Apps with Rich Harris, NYTimes")
SvelteKit, in my opinion, did a fantastic job implementing the best of both server-side rendering and client-side hydration and navigation by default (with any amount of route-level mixing and matching you want to do). I was skeptical of client-side navigation in particular, but it really does make my app feel so much snappier.
Whether you're doing server rendering or client rendering, you need to separate markup from business logic.
Modern architecture fashion tells us that we need to use micro services. So even if I generate markup on the server, I need to talk to micro services using HTTP to get data.
So the question is: which technology provides best tools for writing server-side rendering module?
> Modern architecture fashion tells us that we need to use micro services. So even if I generate markup on the server, I need to talk to micro services using HTTP to get data.
Heres mine: Longevity tech... who benefits from living forever? The wealthy... What does living longer even mean? Does it mean I live 10 years longer in pain? I see longevity tech as code for ensuring the poor are here in the event we stop reproducing, or our decisions prevent us from being able to...
and before you black and white nerds jump on me, Im not talking about biotech and healthcare!
One of the fastest, lowest latency websites I use is HN, and it’s entirely server rendered. It’s also a massively popular website with probably thousands of hits per minute. Anyone who tells you server side rendering is too slow, probably has no idea what they’re talking about.
Server-side has the best chance of providing an ideal experience in the worst case situation: The user's very first visit to the website on a mobile device in a crappy network environment.
Information-theoretic, there is no way you can beat SSR in this scenario. You will not win against a machine that returns a complete HTML document on the very first request if your users only receive hints regarding where to actually find the princess upon their first request.
I look at every client-side argument along the axis of "well now that the universe is already here, we can get started". Server-side explains how that universe got into existence in the first place. Your fancy incremental update shadow DOM system cannot work until it is already bootstrapped via some means.
> Information-theoretic, there is no way you can beat SSR in this scenario.
I think this is generally true, but it does depend on how long it takes SSR to complete. If that's slow, you could potentially be faster by sending a bit of JS+HTML and allowing processing to continue in the background to be fetched later when it's ready instead of waiting for everything.
That said, I think that's a fairly unrealistic scenario since a bad connection with high latency is probably more of an overhead.
SSR that needs to run JavaScript hydration needs to download more content (the html and js bundle) than a spa before it’s interactive.
I don’t know why the community collectively decided that first-contentful-paint is a more important metric than time-to-interactive. Seeing a page quickly and waiting a noticeable amount of time for it be functional seems like the worst possible ux, especially when there is no signal to the user when the JS has loaded.
Even that really requires some nuance. If most of your site is static with a small amount (in terms of data) dynamic content, it could easily be faster to split things up into 2 phases: load the static part and then do a single REST request to get the dynamic part for client side rendering. The first time the user ever visits your page, it will take a small hit compared to SSR, but in subsequent visits the browser can easily cache the static part so it only needs to query for cache coherence (which should be very cheap in terms of throughput) and obviously the REST query for the dynamic parts.
If you do SSR, the client is much more limited in terms of caching because the page contents is not constant. In my opinion, SSR is actually more for slow CPUs than for slow networks since you can make the network usage for client side rendering very efficient as well, but client side rendering will always be worse in terms of client CPU.
Hitting the “Reply” button on HN takes you to a new page with a textbox, taking over 500ms and a complete page reload. On some websites, that amount of latency is acceptable. But that could be instantaneous.
For me this is 45ms to transfer the 2 kB (compressed) of HTML; the whole process takes under 60ms total, which is pretty darn close to "instantaneous" for the "complete page reload."
EDIT: I'm in Texas, so most of this time is probably just round trip time to the west coast.
It's about 120 ms here (wifi off of gigabit fiber, east coast US.) Based on ping time, over 60% of that time is network latency to the west coast. Actual "processing" would be in the 50 ms range which is super fast.
It may be <100ms, but that completely misses my point. My point is that it could be <1ms, and no reload, if the Reply box was added in JavaScript to the previous page.
I'm sure this is an unpopular opinion here, but I hate this website's UX. Replying to a comment loads a new page, losing the entire context of the thread. There is no UI to indicate if there's a reply to an earlier comment made. The typograph is ugly as sin, and hard to read (too small on desktop, looks bad on mobile, poor contrast). With new pages needed for basic reply/editing capabilities, the site doesn't even accurately track the navigation stack. Sure it loads quickly, but we can load a hello world in a p tag pretty quickly too. HN as a site is a perfect example of how bad a SSR experience can be.
Don't know who built this site or how old it is, but the UX is definitely sub-par compared to many other server-rendered sites. Submitting a form and losing the scroll position doesn't happen in every site, even if the page gets reloaded. And the font thing is more of a CSS problem than a SSR/client-rendering problem.
A lot of it could be improved with some CSS changes (scaling etc) as a sprinking of javascript which could handle commenting without reloads. My opinion is that it's perfect for what it is, a discussion board and nothing more. It's not a social media site.
Not that this should be the answer, but there are a lot of HN browser plugins. Most have at least some level of theming and inline commenting. I'm currently a fan of Refined Hacker News (no affiliation) - https://github.com/plibither8/refined-hacker-news - but I'm sure there are others just as good out there.
This reply comes off as needlessly rude, but I'll give you the benefit of the doubt that it's just intent not coming across well via text.
In the context of the comment to which you're replying[0] I'm not sure how else to take your comment. OK, you don't like HN's UX, that's either a comment on SSR and on topic for the thread, or completely unrelated.
> HN as a site is a perfect example of how bad a SSR experience can be.
This is a great ending line if the things you list before it would automatically be better under CSR, or are only capable of being fixed by moving HN to CSR. So, it seems pretty natural to me to assume that you're saying those things (reply notifications, typography, losing position on a reply) would be better under CSR, which is not necessarily the case.
My point is that this site is not a good example to use for showing SSR in a good light. Logically, this doesn't mean the converse of the statement is implied (that if this site didn't use SSR, it would be good).
To be clear, there is a difference between SSR and SSG. SSG is something like PHP, which generates the full page HTML in the backend. I think HN is SSG? Many news websites or wordpress blogs also fall in this category...
I've never heard the term SSG before. Apparently stands for "static site generating" and is a `next.js` thing.
No, hacker news is not a static site. It just makes use of caching HTML on unchanged pages, and as I understand it that cache is often bypassed for logged in users. This is why sometimes when hackernews is overloaded you can still view the site in private browsing, since you're not logged in it hits the cache instead of generating a page for you.
A cache is not a static site, although maybe next.js is redefining the term, I don't know. Get off my lawn.
SSG long predates Next.js. It was by no means the first, but I wrote something that I think could be called a SSG (not the term I used at the time) back in 2010 while the first release of Next.js wasn't until 2016.
Sure, static html sites have existed forever, but I don't know when the term "SSG" was popularized. I assume it was pretty recently all things considered.
Ok, it seems I mixed up the acronyms, I thought SSG stands for server-side generated.
What I actually mean is, that there is a difference between SSR with react, which requires some kind of rehydration on the client, in contrast to a website generated by, e.g., PHP on the server, which doesn't require this.
The PHP website doesn't require the client to rehydrate and produces less load on the client. With the disadvantage, that a subsequent page view requires again a full load, while the SSR loaded react page, doesn't require that.
I didn't check the HN code yet, but it feels like a server- side generated website and not a SSR delivered react (or similar js framework) website...
I assume by SSG you mean static site generation? If so, that's something different entirely. At least in the ways I have commonly seen it used, SSG refers to generation of HTML offline so that all the content hosted is static. For example, in a blog you would generate one HTML page for each blog post. If you were running a blog using some PHP service (such as WordPress), then even those static HTML is what's sent to the browser, the pages themselves are generated on the fly.
If you're talking about static sites, wordpress definitely isn't it, it renders server side every request. (Google's Blogger.com used to be static, not sure about now). HN is likely not static either.
> To be clear, there is a difference between SSR and SSG.
Here's a simple way to think about it.
SSG: there will be a process that generates/bundles HTML/CSS/JS ahead of time with all of the content that the site will have, like the many static site generators out there.
You should then be able to take the output of the SSG process and host it on a dumb web server, like Apache/Nginx.
For example, that's what I do with my HN Personal Blogs site, a set of Python scripts generate HTML output a few times per day, which is then served on an Apache container: https://hn-blogs.kronis.dev/
SSR: there will be a runtime of some sort that will execute any number of scripts on the server, to dynamically generate a response for the user's request.
This is what many PHP and Ruby sites are, if they don't opt to just use those languages for an API. You click on a button in the site, your request is submitted, the language runs some logic on the server and sends you a response, typically there's a DB as well, that most users interact with.
However, you can also mix those approaches. For example, you could make it so that the front page of your site is pre-rendered or at least cached, so that your servers need to do less processing and your DB would be under less load.
That's also what some flat file CMSes like Grav do - so that the articles will load pretty quickly, though those approaches introduce some complexity and the risk of stale data in some cases.
There's also stuff like hydration and many more recent concepts, but that'd get more lengthy.
285 comments
[ 3.1 ms ] story [ 259 ms ] threadMy favorite is when a full react site loads up, doesn’t have error boundaries, hits some unimportant js exception, and the entire page that was fully rendered and ready to go just pops out of existence and you are looking at a white page. That doesn’t seem like forward progress at all.
If a page is presented, it better be f&@king usable
People like to talk badly about w3schools but at least it manages the bear minimum of actually being able to render and display the information I’m looking for.
So has it taken off / is it taking off? If not, why not? Or more to the point of my original comment: Why is something like this just now taking off? Has something new enabled this in the last few years?
It's not a new idea was my point in my comment, so I'm curious why the idea never seemed to take off in the past, and why it might be poised to now.
I don't know enough about any of the frameworks you mentioned to evaluate whether the "hybrid in some capacity" actually does mean this approach has become widely used, but I guess from my experience of using the web, it doesn't seem like it is common, it seems like most applications are still sending a skeleton and then filling the data in client-side, rather than rendering the initial page load server-side.
My experience is that most of the time it’s better to make your public facing site fully SSR and then make the actual app fully client side rendered. You usually don’t need that much interactivity for your public site and your app users don’t mind a few seconds startup time. You also usually don’t need SEO for your app because it’s behind authentication anyway.
Exceptions exist of course.
Those are basically the same drawbacks as a decade ago.
I guess my question to the folks here saying hybrid is the way to go nowadays is: Have these problems been solved in your view?
That aside, just use whatever fits best for the task at hand. If server-side rendering works better for you, use that. If client-side rendering is preferable, do that instead. Or a mix of the two. No need to be dogmatic about it.
I hope by app you mean "webapp", because I sure don't want all my apps becoming websites. That's how Electron becomes more prevalent.
Also, great to see a shout-out to D :)
I really think this should be the first question on a project: Should this be a website or an application? I think the answer to a huge number of technical questions is dependent on the answer to this product question. And it seems like too few people are asking it, and are instead diving straight into making an application (whether web and native).
Money has never existed without taxation
1. Store of Value 2. Unit of Account 3. Medium of Exchange
Of which it's fair to say that several crypto currencies fit that bill.
If you want to think of it as a unit of account, it has to be a state unit of account in order to actually function as money.
And finally I think that the function of money as a medium of exchange is actually a side effect; that is to say that money is the most liquid asset because it is created by an obligation in common to all citizens of a sovereign entity. As such, it is the most likely medium of exchange because it is universally accepted.
However, anything can be a medium of exchange. Hot rocks can be used to heat a room, but you wouldn't call a pile of hot rocks a heater. In the same way, virtually anything can be a medium of exchange, but money (by virtue of being created by the imposition of a tax liability) is the most effective medium of exchange.
My definition of money is: a credit that can be used to extinguish a tax liability imposed by a sovereign. Everything else is a commodity.
Fiat currencies don't have these problems[1]. Because they are instituted by a government that forces people to use it, they have a large volume of economic activity which makes it harder for the currency to swing dramatically in value. The reason why Bitcoin can fluctuate so wildly is because few actually use it like a currency, so there's nothing to buffer against market manipulators and forex speculators.
[0] Because crypto needs global consensus over every satoshi in the system, all transactions need to be widely propagated to all full nodes, which imposes strict limits on how much transaction data can be processed at once. If the limits are too high then only large institutions can run full nodes which is centralizing.
Of course, literally everything else in crypto is centralizing, because centralization is the gravitational force of economics.
[1] No, Zimbabwe doesn't count.
They're charged by the entity that issues the currency (the network/the miners), for the act of using the currency, which I think could reasonably be classified as a form of tax.
Demand for that token is thus entirely speculative and could evaporate at any time. Since there is no issuing authority that guarantees to accept the token in order to exonerate some obligation we have in common the last person holding the token simply loses the game.
Of course many boring posters on HN will never accept that because their models of the world only allow for 1 dimensional villains on the other side of any ideological disagreements.
(Mandatory HN joke explanation: https://en.wikipedia.org/wiki/Render_unto_Caesar plus a pun on the original thread title)
(i.e. he'd reject this as boringly conventional before it got to the level of does it make sense? I've only read a little bit of Thiel, like 2-3 blog posts worth.)
"Title: A Stalin-inspired Look at Webfarm Management
Body: Apocryphally, Stalin once said that quantity has a quality all its own. As such, our hosting system involves an absolutely bonkers number of servers."
Ads causing reflow, embedding of other elements (off-site) with poor performance, the Cambrian explosion of trackers and other cancerous marketing-related cruft, labyrinthine page layouts because someone wanted a pixel-perfect visual. All things which are not the core app itself. This leads me to suspect that most apps would work just fine with a few easily anticipated exceptions.
Large structural changes can often then be made early in the project by a single person or alternate concepts quickly prototyped when it's effectively a monolith -- you don't as quickly get locked into "we'll just have to live with that now"
I'm not against introducing client-side once the final functional form is reached if justifiable gains somewhere -- but from day-one it's usually just a headwind on a project of any complexity
Seems like answering with SSR would fail a Thiel interview for two reasons:
1. It's not important (in the grand scheme of things)
2. It's not a view that very few people hold. SSR was the standard way to do things for a couple of decades up until frameworks like React, and React itself now implements SSR, doesn't it?
Thiel uses this question to try and determine if someone is or can be a free thinker, someone who can discern something to be true even in the face of significant social opposition. That's valuable if you're an investor looking for overlooked opportunities, or an entrepreneur trying to find an edge in a highly competitive market. But there is no taboo or significant social opposition to SSR webapps, and bluntly, no edge to be found there.
> 2. It's not a view that very few people hold.
And yet it makes the author feel a contrarian free thinker. It turns out, it's the prototypical Thiel truth!
There's no attack surface here at all, the only issue with most client-side apps and interaction with server comes from CORS and devs copypasting solutions from SO to get rid of the warning, thus creating the attack surface.
The choices related to displaying appropriate elements based on current user's role that's tied to entire logic of the app has literally zero to do with security.
No, the whole point of client-side rendering is to apply parasitic computing and offload the server by having the client perform work it can thus saving the bandwith and compute power.
Next benefit is application that's "snappy" and works well, which is what almost never happens sadly.
> that’s why you have JWTs and stuff like that.
No, you don't have JWT and "stuff like that" because of this. JWT is for offloading databases so you don't have to talk to a DB on every request since you can verify the token via signature check and thus implement distributed services that don't have to talk to central authority to authorize a request.
> where state is able to be maintained per user usually up by the same thread on the same physical server
And now you're trying to sound smart by adding servers and "threads". I've a feeling you're pulling my leg right now so I'll excuse myself since you started spouting absolute nonsense.
Concerning JWT, I think we were talking past each other as I was referring to a session-less Authentication scheme, which is more or less what you describe.
Finally, there’s no reason why the server can’t render JavaScript as well other parts of the page. In effect, if the server wanted to, it could render of a reactive version or an angular version depending on a variable. Can the client do that?
You have to be sure your data going into the database doesn't have XSS escapes or your rendering of untrustworthy data doesn't have such XSS escapes.
Which is why you shouldn't roll your own SSR unless you are fully aware of this.
SPA doesn't have this problem as it will generally insert DB data into the DOM as text, no possibility of escape or execution by potentially malicious database entries. Not that you can't have issues in an SPA, but you have to do work to bring them about.
If I get a user-provided string from the server as a JSON property and set it via `.innerHTML =`, I have an XSS vulnerability. If I use React's JSX string interpolation, I don't.
If I get a user-provided string from a database and inject it with a PHP `<?= ?>` tag directly, I have an XSS vulnerability. If I use Laravel with Blade templates [0], I don't.
You're not saved from XSS by virtue of using JavaScript to render your code, you're saved from XSS by using a framework that escapes everything by default. Whether that framework builds the escaped HTML on the client or the server is immaterial.
[0] https://laravel.com/docs/10.x/blade#displaying-data
Everything rendered by the server has this potential as it must be deserialized by the browser.
No, but I've definitely seen bespoke, hand-rolled frontend code do it. You can't select SPA frameworks as representative of frontend rendering but look only at hand-rolled PHP from 2002 for backend rendering.
No major SSR framework is XSS-vulnerable by default. Whether you're using Rails, Laravel, Spring, ASP.NET, Phoenix, or whatever, every template engine escapes your strings unless you opt-in with something like Rails's `html_safe`, and they have for over a decade. Unless you've built your own SSR framework by hand with raw string interpolation, the "easy" way to do things is also the right way, just as it is in React.
Yes, congratulations, you pointed out that you can hang yourself either way. That wasn't my point and I acknowledged as much in the first post.
One has an unsanitized escape free method and the other does not.
It's called truth, period, never mind that pillock. There is enough cult of personality in SV already.
JavaScript is eventually needed for any non-trivial app. JS without a build system/dependency management is a maintenance nightmare. JS without linting, TypeScript, module syntax and unit tests is a maintenance nightmare.
Reuse of components is much easier and more testable with framework abstractions (compare a react/vue/svelte component to e.g. a laravel blade component).
Strict separation of CSS, HTML and JS means things like class names drift. With a JS build system you can easily introduce tooling to combat this (auto-removal of unused styles, enforcing that all classes are used, linting for CSS code, etc).
I just can't imagine building an app of more than a few thousand lines without a framework and frontend build tooling. I would end up needing to reinvent these tools myself to ensure code quality as the project grows. I'm not saying it's impossible to add these features into, say, a Django or Rails app, just that it's more work for a worse outcome.
I mean, maybe? Depends what you mean by "many". I'm certainly not advocating for adding JS & frameworks where interactivity is not needed, and as I mentioned, for less than a couple thousand lines, an SPA framework is almost definitely the wrong choice. But my experience in the last 10 years is that very few projects do not grow to the point of requiring quite a bit of JS for interactivity. Async requests, complex client-side form validation, comboboxes, dynamic modals/content previews, showing/hiding long content, 3rd party integrations... these sorts of requirements are in nearly every app these days. And the HTML/CSS only solutions are just not good enough yet, unfortunately.
> And using a backend framework for templating is not mutually exclusive to using a JS build system for helping transpile files and purge CSS and such.
Sure, but at this point, why are you avoiding introducing a JS framework? All that stuff is built in to most JS frameworks (but not backend frameworks). You could piece it together yourself... but for what benefit?
Related, the junior FE devs want our web app to be a SPA because they think it’s the only idiomatic way to write reusable components (think a JSX-written React component). Often they’ve never used anything else (so like TFA mentioned, for them it’s not an open choice).
I hate that my job these days has to involve counteracting this notion, probably looking like some weird Luddite in the process, for simply highlighting the same points from TFA.
Especially for indiemakers and startups by technical founders.
All the frameworks add so much complexity and confusion.
And I have seen several startups fail because when the developer was confronted with breaking changes of their framework, they said "Ok, that's enough. I'm not going to plow through this".
The simple "PHP or Python talks to the DB and outputs an HTML interface" type startups have a pretty good success ratio on the other hand.
You don’t want to deal with processing a raw http request from the web server. You don’t want to split headers. You don’t want to sanitize input params, deal with character encoding, content types, gzipping, cache control, etags, basic authentication, flushing headers, chunking bodies, file streaming, tcp sockets, slow client avoidance, and probably 1000 other things I can’t recall.
No matter how unnecessarily complex you think a http framework might be, I assure you, it’s saving you from a mountain of already solved by people smarter than you or I complexity.
All my projects are 100% my own code down to the core. No frameworks, nothing. There might be some traces of jquery in there from when browsers were more unreliable. I don't even use that these days.
To get to know those frameworks, I built some projects with Symfony, Laravel, Django and some others. But it didn't stick. They are too aggressive in their "do it my way, don't worry what happens behind the scenes, let me do the magic" approach. I had the best impression of Django. That is the only one I might give another try.
Huge difference between working fine, and working right. The security implications of rolling your own, is why I say “you don’t want to…”
Also, none of that code has anything to do with the product you’re actually trying to build. Imo it’s additional maintaining, tech debt, attack surface, and it’s a solved problem by a large community and has more knowledge from the security community baked in, and more eyes finding and plugging holes.
I understand why these are designed that way, but also don’t enjoy using them. Frameworks can feel very narcissistic in that sense, all the code is about them, despite their promise that you’ll focus on your domain more.
I need to play with some of the Kotlin web libraries more, such as ktor or Javalin. There has to be something better out there.
Also, even though you don't use frameworks, I assume you use various libraries to handle web requests and such, right?
When I think about heavy, I think about how hard it would be to replace the framework with my own code in the future. So I don't like magic.
One thing that keeps me from investigating Flask further is that Django seems to be way more popular:
https://trends.google.com/trends/explore?date=all&q=django%2...
So it will probably stay around longer.
Me and other devs maintain this repo which shows how to get from a fresh Debian install to a running web app via different frameworks:
https://github.com/no-gravity/web_app_from_scratch
As you can see, it also has a Flask version.
Contributions are welcome!
As for libraries: PHP has great http and html support build in already. Python is a bit tricky in this regard. That's why I would give Django another try for new web projects. But I also had success just rolling my own http/html code in Python.
Because it is, by far, much larger project? Django has 551k LoC in 31933 commits, Flask has 27k LoC in 5156 commits. Django philosophy is "be opinioated, and bundle everything necessary for developers". Flask philosophy is "do just one thing and just be a good HTTP server, let users pick a solution to all the other problems". Django is a full-blown framework, whereas flask is almost a library. Both approaches are OK, but from your previous message (GP) you prefer lightweight and magic-less frameworks (and Django relies on some conventions to do its magic).
>One thing that keeps me from investigating Flask further is that Django seems to be way more popular:
Both Django and Flask are way more popular that what you're doing (writing everyting yourself. By the way does it mean you write your own HTTP server too?), so I don't know why that stops you. Flask is not going anywhere.
>Me and other devs maintain this repo which shows how to get from a fresh Debian install to a running web app via different frameworks:
Interesting project, thanks for sharing! But that's a bit random - what was your intention when linking it? Also I can't help but notice that the flask example there has three third-party dependencies other than flask (flask-sqlalchemy, flask-login and wtforms). Since you like rolling your own solutions, maybe you would prefer Flask without such libraries? (I personally don't use flask-login and wtforms, and only sometimes use flask-sqlalchemy - I usually use standard sqlalchemy, my custom ORM, or just write SQL directly for simpler projects).
As for Flask not going anywhere - well, all projects go down the drain at some point. Just 10 years ago, the Zend framework was more popular than Django and Flask combined:
https://trends.google.com/trends/explore?date=all&q=django%2...
Good point about the dependencies of the flask version. I did not write it.
If you like to write a pull request which gets rid of the flask-sqlalchemy and replaces it with pure SQL, I would love to see that.
The Golang stdlib does all this for you, no framework needed :)
I honestly think Golang SSR with html templates + a sprinkling of Javascript to enhance is an extremely pragmatic way to go.
You build your entire service into a single binary (assets included with go:embed).
You shed the complexity of the framework AND the web server AND deployment in addition to React etc.
My own personal experience has been working at a large enterprise SSR app that ultimately failed to keep pace with increasing competition (but certainly achieved some success with basic SSR forms in the early 00s), then later worked for a team that had a $500M exit for which the CSR app and backend Node.js API was built with a minimal team size of just a few dozen devs.
I have no doubt someone will bring up levelsio (hey Peter!) and his slew of wildly successful sites SSR sites powered by JQuery and PHP, but I've always felt his stack choice was secondary to his ability to market and quickly ship.
It's a bit of a truism, but I've really come to accept these days that the best stack is whichever one your team is most productive with.
And that iteration speed is key for chasing down product market fit, which is way more dangerous to a company than suboptimal tech.
People get so intimidated by these huge frameworks and get FOMO, that they never try to build something from scratch.
React seems simple, but if you tried to understand what is going on under the hood it would take you months.
Simple should be: can you trace through all the code yourself. Like Backbone.js for example.
Plus, there is already so much rendering complexity under the hood in browser engines. The DOM and CSS are already incredible abstractions available for you to use.
I really don't get what is so bad about just having some object to manage a dom element's rendering.
Create a single relational source of truth for your data. Then create some view models that listen to this source of truth. Then make your objects listen to these view models.
This vdom diffing stuff is so overated.
If you have a list of items, and a new item is inserted, I can just insert that directly into the dom. If I render a different entity and it uses mostly the same dom elements, it's really not that hard to tell say: here are some new props, compare them with your old ones, and do what you think is best. React promises this for the entire app but its all magic. I want control of my rendering so I can make things fast. Debugging perf issues in React is insane. Good luck debugging anything.
> You will need a backend anyway. It'll need to expose data to users. Exposing it as HTML is no harder than doing it via JSON or GraphQL
Sure, if your "app" is just buttons and UI that interacts with a backend DB, I agree. However, many PWAs and native apps do lots of heavy lifting on the client side, and loading the backend with that is not cheap at all!
even more, many backends can be simple CRUD. i reuse my backend for all websites and haven't had to do any custom backend coding in years. so my current backend cost is zero, because i can do it all in the frontend.
It seems like a big deal to me and the entire shift is an indicator of how much the IT community is behind front end clients talking to a separate back end. Server side rendering is no longer considered normal. Server site rendering now means something entirely different. It is about running your frontend code on the back end, So you still have the separation, but instead running it on the same machine. Now the same ui code has to be compatible with two different run times. This is much, much more complex than traditional server side rendering.
I'm glad we now have things like single page apps and client site interactive applications, because some apps were really not possible with server side rendering unless with a lot of Jquery hackery that quickly becomes unmaintainable...
However, I do think that front end technologies are overused, so I agree with the author, And I also think this is objectively a contrarian opinion, considering my initial point.
And maybe server side rendering is just the right answer for websites which are not the two you mentioned.
There is an echo chamber where this happened:
* Facing massive datacenter costs, Google and Meta realized that if they could hand off rendering to the client, they could have smaller datacenters and save a lot of money. Things like React and Angular were born. Other companies with large datacenter costs followed suit, many monies were saved.
* This is when things started to get a little crazy. VCs started pushing heavy client-side SPA this and that because if anyone knows how to cargo cult, it's VCs. Devs started pushing it because it was a hard way to do things and if anything improves your salary, it's being involved with the hard bleeding edge stuff. Also inventing another JS framework turned out to be a great way to pad your resume. Design and UX people realized this was a whole new can of worms they could get paid to open, and dug right in. (In all cases note that the original point, saving money on compute at massive scale, was totally lost, and people just made up new reasons.)
* Outside of this echo chamber which is utterly convinced it's filled with the smartest people in tech, life has actually gone on pretty normally for the rest of us, we're still doing stuff on the server whenever we can, and caching the hell out of everything we can, and being judicious with fancy client side frosting because complexity is generally the enemy. That said, it's definitely true that an entire generation of young web developers has been lost to madness because young web developers also like to cargo cult a lot, and the damage will take years to repair.
But yeah, not really a Thiel truth
I can't think of anyone who doesn't want to save money on servers. Seems like a pretty good general win to me for using the client.
> complexity is generally the enemy
Agreed. But minimizing complexity doesn't require not using a heavy client. You can go fully the other way and make the backend a relatively simple permissions and validation mask on top of a database and let the front end hold all the relevant state.
Use client side rendering and have simplicity too.
I will admit that an SPA turns out to be easier to mess up and design really poorly, but I believe that this is a tooling maturity issue rather than fundamental to the platform. SSR frameworks have had over a decade longer to mature.
Reflecting, I suppose that businesses relying on Php/Laravel or Ruby are probably still enjoying simple SSR development. I've personally transitioned to Java and then .NET, and haven't seen SSR since. Which corner of software are you in, where you see SSR still being dominant?
For one thing, I don't think the motivation of Google and Meta was datacenter costs, though I could be wrong about that.
But it's not that "VCs were pushing client-side SPA", it's that lots of the companies that wanted to build applications, found that they had a set of problems that was best solved by things like Angular. The state of the art before that for highly interactive client-side apps was JQuery, and for a few years, things like Backbone.
Angular solved a real problem - people wanted to build more complex and more interactive client applications in a browser, but just using regular JS (or JS with Jquery) led to really messy applications and was very hard on development.
You can try and handwave all that away as an echochamber, but I think the majority of the industry moved to SPA frameworks as solutions for building client-side apps.
Have you forgotten that these are profit-maximizing companies? Why do you think they do anything? To maximize profits. That is always the answer. If it doesn't maximize profits it's a mistake and they will back away from it.
So for example Facebook either thought that React would increase sales, or reduce costs, otherwise they wouldn't have created it. React hasn't moved the sales needle for them (why would it - they are an advertising company - React has precious little to do with selling more advertising). Ergo it was created to reduce costs. The cost benefit of moving all that compute out to the client is easy to demonstrate and significant for a company of that size.
My own memory of the history of the web is that early web sites with a lot of client-side interactivity benefited greatly from the huge leap in interactivity, and came out several years before JavaScript libraries were widely available for ordinary developers to build web sites with similar functionality. (I'm not counting arguably "non-web" technologies like Flash and Java applets.) The earliest such web sites I can remember are e-mail, calendar, and mapping apps.
Naturally after years of investment in building consumer-facing sites like this, the skills and tools became ubiquitous and arguably overused.
I don't think CSR is going anywhere, mainly thanks to Conway's Law.
If anything, I'd say that with server rendering, separating different modules is easier. You want to rewrite that page? No problems. With client-side rendering there's usually expectation of some monolith project using the single framework.
1. Written in different languages.
2. Completely different deployment paths.
3. Causing completely different ways of scaling.
4. Focus on UI and UX is a very different mindset, with often some people preferring it to be a focus of their work, or not.
It also gets you vastly more choice in language/tooling/etc, even allowing a mixture of different ones, which is what attracts me to SSR. Of course this may change in the future once WebAssembly has had most of the DOM interop overhead optimized away, bringing this freedom to CSR.
The very first step in creating this separation is to define an API that is implemented and operated by backend devs and used by frontend devs. Once you have done that, you have achieved all the clarity that is necessary or possible.
Whether or not some parts of the frontend are executed on the server-side shouldn't matter for the question of who has responsibility for what.
Perhaps it's more about the ease of hiring for different skillsets. If frontend is synonymous with client-side and backend is synonymous with server-side, it makes life easier for HR and recruiters.
I love the 'CHAMP' stack, which stands for CSS, HTML, Apache, MySQL and PHP. ;) Clear separation between frontend and backend.
I'm almost happy that I started webdev in the 90's. This 'ancient' technology is still going strong, with websites and a whole lot of webapps.
Specifically, it depends on context. How big is the app? How many people are involved in building it?
As with many things, separation of front and back ends grew out of web-scale companies and products. If you're buiding Facebook or Spotify or Gmail, then you need a way to partition your app - because you need to partition your people. Humans need structure, we don't deal well with single teams of multiple hundreds.
Many apps don't fit that model. Lots of apps - e.g. business internal apps - might target at most small 100s of users and justify a dev team of < 10. In that world, separation of front end and back end devs & stacks is a disadvantage. Single language, single build apps mean less technical surface for the team to cover. Which means each person can more flexibly turn their hand to the requirements. Most people can do most things end to end. Features are business-driven and end to end. A single PR can deliver a meaningful piece of user-accessible value. There's no unionised demarcation.
None of which says "separate UI & back end is universally wrong". But it's not universally right either. As is so often the case, it degenerates into a discussion that is technical and absolute when the underlying forces are organisational and relative.
You say this as if it is necessarily good, but I disagree and would even say it's actually a hindrance for many teams. It often adds inefficiences, increases costs and makes planning and collaboration more difficult.
> the fact that you get an API by default with CSR is also nice
The vast majority of applications don't need an API.
Yes, and if a single team is doing both it adds another stack to master. This can be a pro or con depending on the size/organization of the team.
It is one thing to push an abstract policy/principle. It is another to hand someone a live, working implementation of a policy and request that they keep moving down the indicated path.
I don't think SSR is a Thiel Truth. I think leadership is. If you want to see more SSR in the world around you, you have to build more SSR experiences and teams around them.
Letting a room full of arbitrary developers sit around a conf call and come up with "the tech stack" is how you wind up in a hurricane of bullshit most of the time. At some point someone needs to ask the question "are we here to make money or have fun?" which should quickly highlight your ideal candidates for CTO/dictator.
SvelteKit, in my opinion, did a fantastic job implementing the best of both server-side rendering and client-side hydration and navigation by default (with any amount of route-level mixing and matching you want to do). I was skeptical of client-side navigation in particular, but it really does make my app feel so much snappier.
Modern architecture fashion tells us that we need to use micro services. So even if I generate markup on the server, I need to talk to micro services using HTTP to get data.
So the question is: which technology provides best tools for writing server-side rendering module?
My wishes:
1. Strict-typed language. 2. Compiler-checked HTML output. 3. Flexible CSS output.
So one should be able to write reusable components and easily write required markup.
IMO best tool nowadays is TypeScript + React.
I can only hope that this is satire
Haskell can do that.
and before you black and white nerds jump on me, Im not talking about biotech and healthcare!
Information-theoretic, there is no way you can beat SSR in this scenario. You will not win against a machine that returns a complete HTML document on the very first request if your users only receive hints regarding where to actually find the princess upon their first request.
I look at every client-side argument along the axis of "well now that the universe is already here, we can get started". Server-side explains how that universe got into existence in the first place. Your fancy incremental update shadow DOM system cannot work until it is already bootstrapped via some means.
I think this is generally true, but it does depend on how long it takes SSR to complete. If that's slow, you could potentially be faster by sending a bit of JS+HTML and allowing processing to continue in the background to be fetched later when it's ready instead of waiting for everything.
That said, I think that's a fairly unrealistic scenario since a bad connection with high latency is probably more of an overhead.
SSR that needs to run JavaScript hydration needs to download more content (the html and js bundle) than a spa before it’s interactive.
I don’t know why the community collectively decided that first-contentful-paint is a more important metric than time-to-interactive. Seeing a page quickly and waiting a noticeable amount of time for it be functional seems like the worst possible ux, especially when there is no signal to the user when the JS has loaded.
This is not SSR.
If you do SSR, the client is much more limited in terms of caching because the page contents is not constant. In my opinion, SSR is actually more for slow CPUs than for slow networks since you can make the network usage for client side rendering very efficient as well, but client side rendering will always be worse in terms of client CPU.
For me this is 45ms to transfer the 2 kB (compressed) of HTML; the whole process takes under 60ms total, which is pretty darn close to "instantaneous" for the "complete page reload."
EDIT: I'm in Texas, so most of this time is probably just round trip time to the west coast.
It's about 120 ms here (wifi off of gigabit fiber, east coast US.) Based on ping time, over 60% of that time is network latency to the west coast. Actual "processing" would be in the 50 ms range which is super fast.
In the context of the comment to which you're replying[0] I'm not sure how else to take your comment. OK, you don't like HN's UX, that's either a comment on SSR and on topic for the thread, or completely unrelated.
> HN as a site is a perfect example of how bad a SSR experience can be.
This is a great ending line if the things you list before it would automatically be better under CSR, or are only capable of being fixed by moving HN to CSR. So, it seems pretty natural to me to assume that you're saying those things (reply notifications, typography, losing position on a reply) would be better under CSR, which is not necessarily the case.
[0] https://news.ycombinator.com/item?id=37237320
No, hacker news is not a static site. It just makes use of caching HTML on unchanged pages, and as I understand it that cache is often bypassed for logged in users. This is why sometimes when hackernews is overloaded you can still view the site in private browsing, since you're not logged in it hits the cache instead of generating a page for you.
A cache is not a static site, although maybe next.js is redefining the term, I don't know. Get off my lawn.
[0] https://michael.mior.ca/blog/designing-an-offline-cms/
What I actually mean is, that there is a difference between SSR with react, which requires some kind of rehydration on the client, in contrast to a website generated by, e.g., PHP on the server, which doesn't require this.
The PHP website doesn't require the client to rehydrate and produces less load on the client. With the disadvantage, that a subsequent page view requires again a full load, while the SSR loaded react page, doesn't require that.
I didn't check the HN code yet, but it feels like a server- side generated website and not a SSR delivered react (or similar js framework) website...
Here's a simple way to think about it.
SSG: there will be a process that generates/bundles HTML/CSS/JS ahead of time with all of the content that the site will have, like the many static site generators out there.
You should then be able to take the output of the SSG process and host it on a dumb web server, like Apache/Nginx.
For example, that's what I do with my HN Personal Blogs site, a set of Python scripts generate HTML output a few times per day, which is then served on an Apache container: https://hn-blogs.kronis.dev/
SSR: there will be a runtime of some sort that will execute any number of scripts on the server, to dynamically generate a response for the user's request.
This is what many PHP and Ruby sites are, if they don't opt to just use those languages for an API. You click on a button in the site, your request is submitted, the language runs some logic on the server and sends you a response, typically there's a DB as well, that most users interact with.
However, you can also mix those approaches. For example, you could make it so that the front page of your site is pre-rendered or at least cached, so that your servers need to do less processing and your DB would be under less load.
That's also what some flat file CMSes like Grav do - so that the articles will load pretty quickly, though those approaches introduce some complexity and the risk of stale data in some cases.
There's also stuff like hydration and many more recent concepts, but that'd get more lengthy.