Hacker News new | past | comments | ask | show | jobs | submit login
Second-Guessing the Modern Web (2020) (macwright.com)
44 points by cdme 12 months ago | hide | past | favorite | 67 comments



I think a big reason that old-school server-side rendering (i.e., templates) isn't popular anymore is that templating languages are horrible and stuck in 2005. An underrated pro of react [1] + typescript is that you get to write your UI logic in regular typescript, and you get real function signatures for all your UI components. This makes it way easier to write reusable components, because you can specify the arguments, and write regular unit tests against them, etc.

With most templating languages, there is no defined function signature (with arguments and types specified), so you get to read through the template to figure out what data to pass in. This makes it very hard to make things reusable. And similarly, templating languages are often some bizarre, janky custom language with pipes and stuff.

At a previous employer, we actually solved this problem. We implemented a pattern that gave us real typed interfaces for UI components rendered with templates on the server. We were doing this the same year that React came out, and clearly had some of the same thoughts as Dan Abramov did, although not in the browser.

I recently started a side-project in javascript for the first time in years, and was surprised to discover that there is apparently no modern open-source library for rendering server side components, other than rendering react on the server of course. Your options are basically react or using some shitty templating language. I went with react.

1: When I say react, please understand it to mean any of the nice modern frontend libraries, like react, vue (is this still a thing?), svelte, etc.


I find the popularity of JSX-style templating really surprising.

    <div>
      <h1>Conditional Display and Looping in JSX</h1>
      <ul>
        {this.state.items.map(item => (
          item.show ? <li key={item.id}>{item.name}</li> : null
        ))}
      </ul>
    </div>
That seems like such an unintuitive way of implementing loops and if statements!

I helped design the Django template language, where the above would look like this instead:

    <div>
      <h1>Conditional Display and Looping in Django Template</h1>
      <ul>
        {% for item in items %}
          {% if item.show %}
            <li>{{ item.name }}</li>
          {% endif %}
        {% endfor %}
      </ul>
    </div>
I do like the type signature aspect of it that you're talking about - I've found myself wanting that for Django templates in the past, to the point that I've started figuring out patterns for populating templates using typed Python dataclasses as opposed to anything-goes-dictionaries.


Maybe because you’re thinking of it like a template language. It is not. It is JavaScript through and through. And mapping over an array is quite idiomatic. So are ternary operators. If you really prefer you can pop that out into a for loop with a full-blown if statement, but that’s not very common—at least not in React.

I think the long history of being served over the wire drove the community to prefer shorter, more terse code.


> Maybe because you’re thinking of it like a template language.

I think they just looked at the JavaScript example, and realized how ugly/unreadable it was, and said "I can do better", and they did. the Django example is actually clear and readable about whats going on.

the fact that the community converged on the current monstrosity should bring great sadness, not rationalizations.


It’s not rationalization. It’s preference. There were plenty of templating languages in Javascript before React came along.


Here's my perspective, as someone who's done a lot of JavaScript app development and recently onboarded into a Django app:

- JSX composes normal JavaScript expressions. That means that every operator/function/etc I have access to in JavaScript is also available within JSX. With Django templates, I need to create a custom tag or filter.

- JSX desugars to a normal JavaScript expressions. That means I can store it in a variable, return it from a function, etc.

- JSX returns structured data rather than a string. That means it can be used to support output formats other than text. This isn't so much of an advantage for web dev, where you want a string, but it's a "least worst" situation if you use React Three Fiber, React Native, etc.

- The aforementioned type safety is nice!

On the other hand, I imagine Django templates are significantly more welcoming if you're more familiar with HTML than JavaScript.

By the way, the ternary in your JSX example can be removed by filtering the array:

    <div>
      <h1>Conditional Display and Looping in JSX</h1>
      <ul>
        {this.state.items
          .filter(item => item.show)
          .map(item => <li key={item.id}>{item.name}</li>)}
      </ul>
    </div>


> By the way, the ternary in your JSX example can be removed by filtering the array

that doesn't make it more readable. its still a blob of typical unreadable functional garbage.


I love Django. I will be the first to throw spears at modern JS dev. Django's template language works well for simple cases. By design, it is restrictive compared to a proper programming language. I find this to be problematic.

For things beyond if/for statements, the solution is usually to write custom tags in a DSL that I have a hard time grokking. With JS, you can write arbitrary logic in an imperative language.


Personally I've come to prefer the design of Jinja, because it supports a larger set of Python syntax. I like that Jinja lets you use full Python expressions.

We designed Django (back in ~2003) with the idea that it should be usable by frontend developers who just worked in HTML and CSS, which isn't really a category that exists much today any more.

We used {% %} for tags rather than XML-style partly because we wanted the tags to remain visible in Dreamweaver!


Nowadays I highly recommend HTML embedding libraries directly in the programming language. E.g. ScalaTags https://com-lihaoyi.github.io/scalatags/ or (my own) https://github.com/yawaramin/dream-html

Yes, you give up the ability of designers and frontend-only people to easily work with the HTML templates. But in exchange you get quite a lot.


Came here to agree with this. Beyond basic conditionals and loops, Django templates get really hard to read IMO. Combine that with “sprinkling in” some HTMX and Alpine and you’ve got the making of a true headache that no one wants to work with, even though it technically gets the job done


Unintuitive? It's just JavaScript, probably indistinguishable from any language that has ternary statements and .map methods.


Yeah, it's unintuitive.

I'm not sure how to back that up... just look at it! Weirdest way I've ever seen to implement an if statement in a template.


I agree that React's (and maybe other frameworks? I don't know them) conditional rendering syntax is very odd.

Like {my_bool && <Component />} instead of (if my_bool then <Component /> else null).

Or {my_bool || <Component />} (which is harder to express in most other languages because of Javascript considering truthy/falsy values instead of boolean true/false).

I am a fan of the UI-as-code approaches (as opposed to UI-as-markup or server-templating approaches) that React has though because of the other arguments you see in this thread, although the syntax could be better for React specifically. Elm is honestly pretty great in my opinion, and Flutter also has a nice language for describing UI as code. React just has less-than-optimal syntax.

I don't have a problem with map, though, except that I would like to extract the mapping function out of the "main view" into its own parameterised function that takes a list of whatever it needs.


What makes it weird for me is the filter/map/etc with an implicit destination, since function chains like that usually get rolled into a variable. It'd get you a compiler warning in Swift or Kotlin ("Result of call to 'map' is unused", etc). Agree that a for loop reads better in this case.


I suppose that depends on whether you look at it as a templating DSL within a JavaScript expression, or expressions within a templating language.

A `for` loop doesn't really make sense from the JS expression viewpoint — `for` loops in JS are statements, and in languages that do treat them as expressions they usually evaluate to the last iteration of the loop. From there, the filter/map makes more sense, since it's an expression that evaluates to an array of template-y stuff.

If you see it primarily as a templating langauge, though, the `for` loop makes way more sense — every iteration, it's adding a string to the template.


A subset of Javascript though.


Personally I think ternarys should die in a fire. I despise them. Like, of all the thing validly deserving of syntactic sugar... that's the case that's "important"? It's neither especially common, nor is the sugar very nice to read.

As soon as you need a 3rd leg you have to rewrite it as a full blown if/case/whatever anyway.


Not sure why this is getting downvotes. Ternaries are at best a necessary evil in JSX. We'll all be rejoicing when pattern matching finally lands in JS [1].

[1] https://github.com/tc39/proposal-pattern-matching


If you do proper server side rendering you wouldnt even have if statements in the template. your backend code should have divided everything into correct buckets for you to iterate through them. application logic shouldnt be in your view.


I wonder why JSX didn't just go all the way with the language (arrays and objects) to represent html tags and attributes, it would have cut the noise by 50%.


> templating languages are horrible and stuck in 2005. An underrated pro of react [1] + typescript is that you get to write your UI logic in regular typescript,

Yeah exactly, which is why I always recommend DSLs that embed HTML directly in the language. E.g. https://com-lihaoyi.github.io/scalatags/ or (my own) https://github.com/yawaramin/dream-html

They make writing HTML a breeze with the full power of the programming language available.

> We were doing this the same year that React came out, and clearly had some of the same thoughts as Dan Abramov did

Dan Abramov is not the original creator of React. That was Jordan Walke: https://www.youtube.com/watch?v=GW0rj4sNH2w


I've run into this same issue when developing a DSL for generating language bindings and doing data serialization. Not having compile-time type safety is such a pain.

So I'm extending the language to feature statically typed string templates as well. It currently targets (generates) C++, but I'll add other language targets in the future.

It's still a work in progress but I just flipped the repository public in case you want to follow along as I work: https://github.com/dpemmons/typedef


I've still found nothing that can match up to what Wicket was doing 10+ years ago. Your are self-contained, and know how to render their own markup. Any "templates" live with the components and are tightly coupled to them. Control flow lives in code and code alone; your markup specifies ids where your code can attach components, but there's no way for your markup to call back into your code, so you avoid spaghetti. It's wonderful.


"Moderately interactive interfaces" describes most web applications - stuff like gmail, airbnb, facebook, youtube, reddit, etc. Even for things like Mapbox or Observable that require a high performance core, React is the best choice for building the surrounding chrome.

Whether HTML/CSS/DOM was a good technology to use for building these types of applications is another question but we're stuck with it now either way.


Sometimes I wonder how many criticisms of JavaScript frameworks are driven by a nostalgia for an internet that no longer exists. Not this post per se, but many seem to forget why the industry landed on React in the first place.


Featuritis...the drive to add "features" because other sites do.


I'm pushing GridWhale, which is a completely server-side platform, but the trick is that we remote the UI to the browser (think X-terminal but at the granularity of UI controls).

The nice thing about this is that your program doesn't have to worry about the front-end/back-end split. You just write as if you had full control over the machine, and the platform takes care of remoting to the browser.

Here's the reference manual for it: https://gridwhale.com/program.hexm?id=GCJ5TL7Z&file=GCJ5TL7Z...

[Be gentle--this is implemented as a GridWhale program and everything is still a prototype.]

And here's a post I wrote on the motivation: https://medium.com/@gridwhale/rise-of-the-hyperplatforms-d4a...

EDIT: 15 minutes after this post, I've already had 20 clicks, and each click spawns a new server-side program. And it's just running on a little 4-core Xeon PC under my desk.

I'll post again when it all falls over!

EDIT2: Not as bad as I feared/secretly hoped. After an hour there are about 100 program instances, but obviously most are idle, so they don't take up too many resources. The compute process is only using 32 MB of working memory, so we have plenty of room for more. My guess is we could easily hit 1,000 program instances. Of course, this kind of traffic is trivial for a standard web server--we're talking something like 50 requests per minute. But you gotta start somewhere!

EDIT3: Spoke too soon! Finally crashed. Although not from traffic but from a bug, so now I have something to debug.


Why is every clickable element implemented as a div? You lose out on a lot of native things, like changing mouse cursor on hover, keyboard navigation for users with special accessibility needs, etc.


Good point! Yes, for lots of things I need to use <a> instead.

Again, though, I want that to be handled by the platform, as much as possible, so that devs don’t have to.


<a> or <button>, depending on the function


Agreed. And obviously we'd implement all the ARIA stuff.


> Era 2:62.

Hm. Custom SemVer, custom language, custom GUI framework? It's a lot.


Dude, I'm a software engineer. I like writing software.


I think what he's trying to say, is that's a lot easier to convince someone that one thing is a good idea, rather than about 7 untested, unknown things all at the same time. Conventions are, well, conventional for a reason.


Absolutely true! And that's one of the 1,000 reasons why GridWhale might fail.

There are already lots of people working to simplify web development by fixing one thing at a time. But what if we could start from scratch and build an integrated platform in which all the pieces work together? Would that be better than piecemeal evolution?

Take something like https://Bubble.io. That's an integrated system which has its own custom semantics for UI, storage, etc. But people build apps on it because it's really easy to build apps.

My premise is that there are some people who are looking for an integrated development experience (like Delphi or like Visual Basic) who are not satisfied with either current complex tools or the more limited nocode systems like Bubble.io.

Will there be enough of them to build a business? We'll see.


(2020)

Folks, this is exactly what htmx (and Phoenix LiveView and Laravel Livewire and Rails Hotwire) solves. OP was almost there but couldn't quite articulate this niche. Which is OK, we have the benefit of hindsight now.

Try htmx. It will blow you away with its simplicity compared to (today's) React. My personal recommendation: try it with dream-html, a library I wrote for expressing HTML directly in the language: https://github.com/yawaramin/dream-html (or some similar library).


IMO, React's popularity has little to do with productivity in the context of what other tools are available (many of which we never even heard about). It's mostly about network effects. Popularity is the primary reason why companies use React as it suppresses developer salaries by making devs more interchangeable. It creates liquidity in the market for dev talent due to shared familiarity. Had the similar kinds of network effects existed around a different, better framework, all companies would be much more productive. And even then, I would say the benefits of network effects are greatly exaggerated.

Also, it's important to note that many developers who are good at putting together functionality in React quickly aren't necessarily good developers in the more general sense (in the long run). This can cause problems later in terms of security, maintainability, performance, hiring (due to complexity of the software itself scaring off prospective hires; familiarity with the stack isn't everything) also there are concerns about operating costs, vendor lock-in and scalability.


HTML and DOM lack too many common and expected GUI idioms (see link). If our standards had those, then we wouldn't need to use clunky stuff like React to emulate them. We need a state-ful GUI markup language standard.

https://www.reddit.com/r/CRUDology/comments/10ze9hu/missing_...


HTML and DOM lack those because that’s not what they’re for. Stop trying to build desktop and mobile applications using a document markup language. If you’re building a client-side application, use the platforms’ native languages and technologies.

It should be possible to port a modern browser engine to an average new PC from 1995 and use almost the entire web, over 33.6K dialup, with good performance—modulo high-res/quality images, audio, and video. That we’ve allowed the web to get away from this says way more about web development than technology.


> HTML and DOM lack those because that’s not what they’re for. Stop trying to build desktop and mobile applications using a document markup language. If you’re building a client-side application, use the platforms’ native languages and technologies.

People love to say this here but I've never seen a good reason for it. Web technologies are far and away the best I've used for creating user interfaces. And there are significant advantages to building on the web. How else can someone jump into collaborating on a document or a picture with me — without installing anything — after receiving only a short text?


>How else can someone jump into collaborating on a document or a picture with me — without installing anything — after receiving only a short text?

To be fair, that doesn't require HTML and the DOM, it just requires a network. It just happens that the network we have is used to serve HTML and everyone already had the app installed (browsers) when "web apps" became a thing.


Indeed, some of us were doing it many years ago in native applications, no HTTP involved, on hardware a fraction as powerful as the average smart watch.


What is "it" in that sentence?


The thread is about collaborative applications.


Do you care to, like, describe what you’re talking about?


HTML and DOM are genuinely poor media for doing that though. A lot of web development is working around them.

However, it’s the only common UI we have. It is defined outside the scope of any one platform. And if you want to serve HTML, you have to conform to the spec.

There is no UIML. If there were and if it were served via HTTP, we could have all of what you want AND a better web development experience


Okay, but why do you say that? How is <insert favorite native UI toolkit> better?


All native toolkits are better to work with for UI than HTML+DOM.

To paraphrase: saying HTML+DOM is great because it works everywhere is like saying anal sex is the best because it works on everyone.

Eventually, in any significantly complex application, you will have to work around the DOM. Or kick to rolling your own controls because HTML doesn't have what you need. React, Angular, Vue, Bootstrap, Tailwind, Material, the others, they all exist because HTML+DOM is not made for what it has been forced to do.

"Centering a div" is a meme for a reason. You don't have those problems with native UI.


> Web technologies are far and away the best I've used for creating user interfaces.

Which other ones did you try? Because web technologies weren't even designed for creating user interfaces.


They very much were.


There is a very clear market desire for desktop style apps delivered through browsers.

Users love it. Users hate installers. Users hate updates. Webpages have neither.

Companies love it. Makes subscription access apps easy to sell. Makes it easy to target all platforms and keep costs low.

Seems very flippant to completely dismiss the dominant trend in this industry over the past 20 years as simply wrong.

I agree the technologies are not well suited to this purpose which is why I avoid frontend at all costs. But powerful web apps generate a lot of value for a lot of people, myself included.


Nah. This “dominant trend” exists because companies are always trying to get developers as cheaply as possible, not because pretending web pages are applications actually provides real productivity or usability or even deployment benefits over the long term relative to native applications.

Some of us have been in this industry long enough to see the same promises come around several times in various forms and they’ve always been bullshit. Thats why I don’t participate in it and stick to native development.


I disagree. Most of the "interactivity" is attention-stealing anti-patterns that no sane person actually wants.

News sites with scrolling auto-playing videos, overly-complex SPAs that are slow when you just want to get this specific task done, newsletter subscription modals, the list goes on.

True "webapps" are rarer than we've been lead to believe.


The hoops that need to be jumped to get a web version of a simple tableview/datagrid with sortable rearrangeable resizable columns and recycled rows like desktop UI toolkits have had since the dawn of time are a bit nuts.


To be honest, a lot of that is stuff that I'm happier to not see on a webpage.


We have started our platform before React, but ran into similar issues. Luckily they are surmountable. Many of them can be solved by inlining the CSS and basic JS into the page when the session cookie is missing. Then install a service worker to cache each inlined file and show them next time they are requested.

There are nuances like rewriting URLs in the CSS to be relative to the page, and then replacing them back in the service worker before caching the result.

https://community.qbix.com/t/qbix-websites-loading-quickly/2...

But you don’t need static sites. You can use CDNs to cache your pages and make them effectively static. Use AJAX or ESI / SSI to include stuff that depends on the session cookie.


I very much agree about the point about Server Side Rendering. I don't like it. There are some fundamental differences between front end and back end which should never be neglected. Critically, considerations related to authentication and access control but also relevant in terms of performance (e.g. caching and bundling as described in the article SSR is just a bad idea in practice; I've never seen a project make good use of it)...


Related:

Second-guessing the modern web (2020) - https://news.ycombinator.com/item?id=27308982 - May 2021 (296 comments)

Second-Guessing the Modern Web - https://news.ycombinator.com/item?id=23136688 - May 2020 (453 comments)


Flagging because Tom has expressed that he doesn’t want Hacker News to link to his articles.


I'm curious: Why? Too much traffic? Does he have a beef with HN?


HN comments can be very negative, and he found himself adding a bunch of caveats and qualifiers to his writing to appease the critics, which he feels makes his writing worse.


Yeah, that makes sense. Thank you!

I'll just say that from my perspective, the only thing worse than having critics is not having critics.


Yeah, I personally feel lucky when an article of mine hits the front page (although maybe there's an inflection point of popularity at which the reverse is true). But regardless, we should respect his wishes.


With tech trends, over the past 15 years, I was always on the ball 100% of the time until React came along. I started coding Flash/ActionScript games around 2004 (which is based on ECMAScript spec just like JavaScript) and I was using ActionScript 3 with types which was very similar to TypeScript but was better (it was simpler with less room for unnecessary type gymnastics). I was a web developer before the term was broadly used, I was a front end developer before the term was broadly used, I was also a full stack dev before it was trendy.

I was an early bird JavaScript single page app developer. Early bird Node.js adopter. Early bird NoSQL (e.g. MongoDB) adopter. I was always on the cutting edge, adopting new tech as soon as I heard of it but just before it became super popular. I was 100% on target until React came along and I've since been wrong about most trends and yet I'm becoming convinced that it's the trends that are wrong, not me. I say this because complexity has gone out of control and I can build apps faster and simpler using my own home-baked stack than other devs can with React, GraphQL or other trendy tools.

Most of my tools/libraries are open source but they get limited exposure to the broader community (in spite of very positive feedback, I can't get past the chicken and egg problem) so I just use them for myself. If you saw how I write apps (with auth, modeling complex relationships between data, automatic real time update, can scale out of the box with sharding on Kubernetes etc...) with very little code, many devs would be impressed want want to use or build something similar from scratch, yet they may never learn of this tooling or this coding philosophy. These days, new tools simply cannot get the initial boost of users that is required to gain traction. It's like they cannot even enter the playing field; no surprise then that they cannot win the game. You can see how the discourse is completely suppressed; there is only one set of tools on the front end nowadays; React and TypeScript. VueJS and Svelte are struggling if you look at job adverts even though they are at least slightly better technically for most scenarios; it does not translate to jobs.

I think the reason why there is a dissonance between getting very positive feedback for certain open source tools and there being limited adoption is because, at the end of the day, developers don't have a say regarding what tools they can use in production at the companies they work for; they are completely limited to well-known existing tools.

It follows a more general problem we're facing in society now; there is a belief among elite circles that we've reached some kind of singularity; that everything has been figured out and is in its optimal state so no need to try anything else. "Trust the science"; imagine doctors saying that 100 years ago... It says something about how some people perceive this moment in history; they perceive today unlike any other moment before it; whereas in reality, things are very far from optimal for many reasons and we are still in a transition phase.


What are some of those lesser known tools to build web sites/apps?


Web Components (HTMLElement). This is native to all modern browsers. It's possible to build complex single page apps with them without any framework and the code is often much simpler and more readable.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: