Hacker News new | ask | show | jobs
by podgorniy 329 days ago
I think people are now ready for php. I bet it will be reinvented on top of nodejs.
14 comments

At some point I hope it becomes obvious that well-engineered SSR webapps on a modern internet connection are indistinguishable from a purely client side experience. We used this exact same technology over dialup modems and it worked well enough to get us to this point.

Being able to click a button and experience 0ms navigation is not something any customer has ever brought to my attention. It also doesn't help much in the more meaningful domains of business since you can't cheat god (information theory). If the data is so frequently out of sync that every interaction results in JSON payloads being exchanged, then why not just render the whole thing on the server in one go? This is where I can easily throw the latency arguments back in the complexity merchant's face - you've simply swept the synchronization problem under a rug to be dealt with later.

Yes, a well-engineered SSR webapp could be indistinguishable from an SPA. However, it is much harder to build a well engineered SSR with the tools we have. I haven't seen someone solve errors with form submissions and the back button well at the framework level. Post-Redirect-Get was awful. Trying to solve back buttons and wizards. Trying to solve modals. Is a modal a separate page with the rest in the back? What does closing a modal mean? What does a sidebar mean? How about closing it? Pretty soon, you're in half-an-SPA already.

And since you don't want a 2000 character URL, you're either storing half of the session on the server or having to build an abstraction with local storage. And since our frameworks didn't evolve to handle that, what is the purpose?

The key insight into the SPA is that you are writing a coherent client experience. No SSR framework figured out how to do this because they thought about pages rather than experiences.

Let me be clear: I am speaking about web applications. If you're providing information and only have a small number of customer interactions, an SSR is superior. CNN should not be an SPA.

All of the SSR webapps I've built had these solved at a framework level. Dot net and PHP.

Like, the back button: there is no logic because this isn't react. It's just the browser back button. You don't have to do anything if you're using SSR. Back button problems only apply to SPAs or hybrids.

The only real use case for an SPA is something that has to continue to work offline. There are legitimate cases like this, but most apps developed as SPAs aren't it.

> No SSR framework figured out how to do this because they thought about pages rather than experiences.

Laravel, Blazor and apps designed around HTMX are all like this. "SSR framework" has literally nothing to do with "pages rather than experiences". Pages are just a medium to deliver experiences.

> The only real use case

The original idea behind an SPA was to enable API-only backends (with static file service). I still think that's a very worthy use case.

Why not decouple the backend from the concerns of particular views? It makes for a more complex frontend, but it also allows multiple, highly differentiated frontend apps to be build on top of a single set of backend APIs. Esri's ArcGIS Online powers a lot of specialized frontend-only web apps. I used to be on their Business Analyst team (that's a web app) - and I have to say I really like the pattern of building apps this way.

That's not a use case, that's an implementation. What is the end user actually getting with this architecture that can't be obtained by the server-side one? Offline functionality is the only differentiating feature.
A use case for an architecture pattern is a way it could be used to implement something. The concept of a "use case" doesn't just apply to end-users of a software product.

> What is the end user actually getting

More things implemented in the products with less development time.

For ArcGIS? Have you ever used that?

A similar system would be Figma - how do you build a server side Figma?

> Yes, a well-engineered SSR webapp could be indistinguishable from an SPA. However, it is much harder to build a well engineered SSR with the tools we have.

Clearly you've never used Laravel + Livewire. Modals, forms, wizards, sidebars, I have all of that in my app without writing any client-side JavaScript. And it works better than most SPAs. I actually get gushing praise for how "smooth" the app experience is.

My contention is that this may not be the traditional client side app, but you are still placing these on a single page. Just because you are replacing the HTML on the page doesn't mean it is a multi-page app. It's an interesting SPA/MPA hybrid but just because you are not writing javascript doesn't mean that the infrastructure isn't using javascript to handle the plumbing.

So, let's use this as an example. Let's say you bring out a side drawer to edit the details of one row on the table. The side drawer pops up. The user edits details and clicks submit. (To answer this question, the user scrolls to other parts of the table to look at other rows.) There is an error in the user's input based on business logic. The user corrects it, and the row is changed. The side drawer goes away.

How many times is the whole page loaded from scratch? In a traditional SPA, the page is loaded once. With a strict MPA, the page is loaded from scratch four times. With Laravel + Livewire, to my understanding, the page is loaded once and divs are replaced with HTML from the server.

Even if it is not a react app, it is still a collection of single page apps with server side intermediations using html.

> The key insight into the SPA is that you are writing a coherent client experience.

This is the best way to put it I've yet seen. HN articles keep saying things like "now that navigation transitions are solved in CSS, there's no use case left for SPAs". Is everyone just writing apps for widespread content consumption or something?

> CNN should not be an SPA.

Yes, and we need canonical "that should be an SPA"-type apps to bring up in these discussions--which can be hard, since all the best SPAs are for getting work done, not publishing content for the public to consume. Thus, as a class they tend to be department-procured B2B apps and not as generally recognizable. I propose GMail and Google Docs/Sheets/Slides for starters.

I think the easy answer is "could you see this system being rewritten in QT or Visual Basic 6?"

If this would have been a desktop app in the 90s, it's within this scope.

> At some point I hope it becomes obvious that well-engineered SSR webapps on a modern internet connection are indistinguishable from a purely client side experience.

I dunno; other than the fact that there are some webapps that really are better done mostly client-side with routine JSON hydration (webmail, for example, or maps), my recent experimentation with making the backend serve only static files (html, css, etc) and dynamic data (JSON) turned out a lot better than a backend that generates HTML pages using templates.

Especially when I want to add MCP capabilities to a system, it becomes almost trivial in my framework, because the backend endpoints that serve dynamic data serve all the dynamic data as JSON. The backend really is nicer to work with than one that generates HTML.

I'm sure in a lot of cases, it's the f/end frameworks that leave a bad taste in your mouth, and truth be told, I don't really have an answer for that other than looking into creating a framework for front-end to replace the spaghetti-pattern that most front-ends have.

I'm not even sure if it is possible to have non-spaghetti logic in the front-end anymore - surely a framework that did that would have been adopted en-masse by now?

> Being able to click a button and experience 0ms navigation is not something any customer has ever brought to my attention

With modern CSS transitions, you can mostly fake this anyway. It's not like javascript apps actually achieve 0ms in practice - their main advantage is that they don't (always) cause layout/content flashes as things update

Complexity merchant... I like that.
> Being able to click a button and experience 0ms navigation is not something any customer has ever brought to my attention.

"it's too slow" is a thing a lot of customers have mentioned to me over the years.

> modern internet connection

Have you heard of these things called smartphones? I hear they're getting quite popular.

I read HN all the time on my phone, and I love that it loads reliably even on 1 bar of 4G. Meanwhile, Reddit no longer works reliably even with 3 bars of 5G.

The former is HTML with a light sprinkling of JavaScript, the latter is a SPA app.

What about a feature like query completion?
The query completion can also be SSR. The example below is HTMX for Active Search, but the principle is the same:

https://htmx.org/examples/active-search/

I suppose that is a rather neat way to do it.
SSR doesn't mean "no JavaScript." See "progressive enhancement."
html native datalist?
The behaviour of an HTML datalist is basically completely different in every browser. It is a highly flawed element.
there probably is a jQuery plugin for that /s
I actually started my own PHP based on C# called CHP for fun.

It runs atop whatever the current dotnet hosting service is (Kestrel?). It takes everything inside the "<? ?>" code blocks and inlines it into one big Main method, exposing a handful of shared public convenience methods (mostly around database access and easy cookie-based authentication), as well as the request and response objects.

Each request is JITed, then the assembly is cached in memory for future requests to the same path, and it will recompile sources that are newer than the cached assembly.

There is no routing other than dropping the .chp extension if you pass "-ne" into the arguments launching the server.

It's not very far along, and is completely pointless other than for the sake of building my own web language thingy for the first time since 2003.

Have you looked into the string interpolation & verbatim operators as a templating alternative? These can be combined to create complex, nested strings:

  var reportPartial = @$"
    <h1>{report.Name}</h1>
    <table>
      {string.Join('\n', report.Items.Select(reportItem => @$"
        <tr>
          <td>{reportItem.Col1}</td>
          <td>{reportItem.Col2}</td>
        </tr>
      "))}
    </table>
  ";
In more complex views or reuse scenarios, I'd push the inner interpolation loop to a method.

This is how I've been building my .NET web apps for the last ~3 years. @+$ = PHP in C# as far as I'm concerned.

Some dangers with injection attacks if you don't santitize inputs correctly, but this is probably faster than most templating languages like razor.
There are a lot of ways to manage this problem. My preferred path is to wrap interpolated fields with HttpUtility.UrlEncode() when I know a user can touch it and there are plausible reasons for allowing 'illegal' characters at form submit time.

In terms of performance, it is definitely faster. The amount of time it takes to render these partials is negligible. You'd have to switch up your tooling to measure things in microseconds instead of milliseconds if you wanted any meaningful signal.

The only thing that would be comparable might be something like RazorSlices.
It's super easy to add sanitization middleware in .NET.
As a long time PHP developer, it never fails to amuse (amaze?) me the lengths people go to in order to get the things the browser will give you for free.
The most "special" code that I regularly come across is when a developer takes a JPG in blob storage -- already a public HTTPS URL -- then serves that in a "Web API" that converts it to base-64 encoded bytes inside JSON, sends it to client JavaScript, decodes it, and feeds it to an image in code.

Invariably, it's done with full buffering of the blob bytes in memory on both server and client, no streaming.

Bonus points are awarded for the use of TypeScript, compression (of already compressed JPGs, of course), and extensive unit and integration tests to try and iron out the bugs.

This is truly beautiful. Art, even.
The browser gives you a full-blown programming language with a rich API, but it seems a lot of people avoid that in favor of smushing together a static view on the server side with little more than string interpolation.
HTML templating isn't just string interpolation, Its a whole templating engine. It's not like JSX, which is fake templating. Server side frameworks have real templating.

Plus, you have to convert data to HTML somewhere. If you're using react you do this typically on the front end. You traverse and read JSON and convert it to HTML... Just like you would in PHP. Just, on the front end.

> You traverse and read JSON and convert it to HTML

It gets converted to DOM nodes, and there is zero HTML source involved when using a component toolkit. Whereas in PHP, you can do things like this and it won't make a peep:

    $foo = '<h1 <um & hi=="bla""foo"""arglebargle>>>>>';
    ?><?= $foo ?>
Other template engines like twig or blade will at least escape it by default, but of course have a syntax for interpolating it raw, otherwise they wouldn't be very useful as template engines. That's the sort of templating I'm talking about. JSX is a tree builder syntax that doesn't even produce strings at all on the client side, and when rendered in SSR, produces HTML source that's correct by construction (syntactically anyway). You can call that "fake templating", I'd say it's not templating at all.

Obviously there are other server-side template engines out there that are also correct in this fashion (HAML comes to mind), but I'm not referring to those, and neither is most of the "server-side is all you ever need" crowd.

I haven't seen a project that uses PHP for templating in many, many years. PHP backends use a templating engine, not PHP. They also feature components.

Its the same level of abstraction as JSX but you also get type checking.

I would love to see more server template engines on the abstraction level of JSX/TSX or better, but I can assure you that neither Blade nor Twig are among them. And I actually like Twig (yes, I still occasionally do templating).
I'd prefer not to download 2MB of JavaScript and feel my phone get uncomfortably hot just to fill out your online form.
That's just bad coding no matter the framework. Too many devs pull too many packages in....Saving themselves minutes at the expense of all the users waiting longer. So much compute and co2 is wasted on it.
Like a super rich and very well tested front end client, that doesn't need a server to template everything for it?
php is great but I’m surprised by how people are not discussing htmx.

It’s a chance to start all over yet again! Come on- we’re all up for that, we do it every few months!

smdh!
Glad I skipped the whole "JavaScript only" webdev phase. My mad PostNuke skills are relevant again.
I'm voting for Cold Fusion on top of Golang.
Too advanced typesystem for Go folks, better keep it on top of Java. /s
Indeed, the Platformatic folks announced just that last week:

https://blog.platformatic.dev/laravel-nodejs-php-in-watt-run...

I feel revindicated for staying with ASP.NET and JavaEE/Spring all these years.

Next.js is kind of bareable, as it uses the same approach, going back to the roots of web development, it is almost as doing JSPs all over again.

I'd love to see a modern PHP without all the warts but with the ease of use.
I think you are in for a treat, then, because PHP 8 is way different from PHP 5.
Unless they have abandoned backwards compatibility then I don't think that is what I meant.
Major differences that I can think of between the two are (with regarding to warts and ease of use):

PHP 8 uses exceptions with a unified Error hierarchy, there are type errors, division by zero, certain parse errors and so on.

PHP 8 has strong support for static typing now, thank goodness.

PHP 8 introduces union types (int|float|null).

PHP 8.1 introduces intersection types (A&B).

PHP 8.1 added the "never" return type.

PHP 8 has less repetitive boilerplate.

PHP 8 has consistent function signatures now.

PHP 8 has consistent object/array syntax now (to be honest, some asymmetries remain).

PHP 8 has named arguments for clarity and flexibility.

PHP 8 has the nullsafe operator which simplifies deeply nested null checks.

PHP 8 has arrow functions which makes closures concise and easier to use.

PHP 8 has attributes, e.g. "#[Route("/users")]".

PHP 8 has "match" expressions which is a more predictable, type-safe, and expression-oriented alternative to "switch".

PHP 8 has many more tools for testing and debugging (incl. static analyzers).

PHP 8 has many new functions (incl. utility functions).

PHP 8.1 introduces native enums.

PHP 8.1 has "readonly" properties for enforcing immutability.

PHP 8.1 has cleaner syntax for referencing callables.

PHP 8.1 has "fibers" which enables cooperative multitasking and is a foundational building block for upcoming async/await features.

Global namespace pollution has been pretty much resolved (Composer autoloading[1]).

There are other ecosystem-level improvements such as PSR standards[1], better async story, etc.

This list is non-exhaustive. These are just the improvements that come to mind off the top of my head so I probably missed a lot of other major improvements. PHP 8+ is definitely much easier to use and they greatly reduced PHP's warts. There may be some inconsistencies left here and there, but they are not a deal-breaker IMO, if you even run into them.

[1] https://www.phptutorial.net/php-oop/php-composer-autoload/ (I do not use "dump-autoload"), https://github.com/php-fig/fig-standards/blob/master/accepte..., https://www.php-fig.org/psr/psr-4/ (https://www.php-fig.org/psr/)

---

I strongly recommend taking a fresh look at PHP 8+. It is very different from the PHP you have once known. It is "modern" now. There are lots of deprecations and removal of old warts. I did not like PHP as much ages ago, but it was a pleasure to use PHP 8+.

If you are looking to (re)learn PHP, the book “PHP & MySQL: Novice to Ninja” is a good starting point[1]. There are many other, high-quality books and resources as well.

[1] Available on libgen. The source code examples from the book are available on GitHub: https://github.com/spbooks/phpmysql7.

---

If you have any specific warts or whatnot, or if you want more resources, please do feel free to let me know.

---

I wrote this comment on my phone, so it is not as detailed and it is not structured as well, but I hope that it will still provide some insight into the differences between legacy PHP and modern PHP.

Happy to answer any questions!

That's great but unless you have given up backwards compatibility then you are still going to have all the warts.
Additionally, PHP 8.5 will have the pipe operator.

https://thephp.foundation/blog/2025/07/11/php-85-adds-pipe-o...

Wow very in depth comment. Maybe I'll spin up a dev container and play around with php
I missed an important difference (because I did not consider it to be relevant to "warts"[1] and "ease of use"), which is that modern PHP has Just-in-Time (JIT) compilation now, not an interpreted runtime, which offers significant performance improvements!

[1] On second thought, poor performance could be considered a wart.

That’s called Python or Ruby.

I’ve been building web apps since the ’90s, and I never understood the appeal of PHP. It was always a terrible language, and there were usually better alternatives available.

It’s about time. We already reinvented Lotus Notes.
Lotus Notes was great until they added email.
Given you can run Doom on your fridge these days, it should be absolutely no surprise that you can already run PHP both in the browser and in Node [0].

[0] https://github.com/asmblah/uniter

It has been wild to realize I've now seen one full technology cycle of thin client to thick client to thin client again. Maybe PHP this time around will be able to be more robust with the lessons learned.
program like it's 1999
It’s called nextjs
I think they go with a PHP implementation on WASM so it runs on the client