Is this sarcasm? While it may be true that my mother does not know what ffmpeg is I'm almost positive she interacts with stuff that uses it literally every single day.
I mostly agree with you but React isn’t just JavaScript. JSX is not JavaScript. It’s just that we’re so used to it we don’t consider it notable any more. Worth keeping in mind when you’re looking at a brand new framework.
There are a lot of things people might mean by claiming that something "is just JavaScript," but one possible meaning is that the source code you write can run in the browser without any build whatsoever. For React, that's true with the exception of JSX, which is a very simple and optional syntax transform. (Of course in practice you'll probably want to do module bundling too, but browsers could technically load your ES modules directly from static file storage.
For Marko, that doesn't seem to be the case, but it also doesn't really make sense given the problems that Marko is trying to solve.
Another thing people might mean by "it's just JavaScript" is a much more subjective notion about how similar the overal syntax, control flow, etc. feels to whatever previous JavaScript experience the person has. This meaning is a lot harder to pin down, and in most cases reasonable people could disagree on what is and isn't "just JavaScript" according to this meaning. That said, I would tend to agree that React's templating uses normal JavaScript control flow and composition primitives more so than Marko.
JSX was such a breath of fresh air after having written and maintained apps which used both of these formats for years (and also having written a library which supported both of them for reusing the same templates on the server and in the browser) - it's the commas! I'm glad it's everywhere now.
But that was also back in the days when trailing commas at the end could break things, JavaScript editor support was relatively poor, and tooling wasn't where it is now (knowing your code is once again valid because the autoformatter just kicked in).
This looks like what JSX compiles into. You can do the same (or similar) with React by using `React.createElement` instead of `m` (or just alias it) so you don't need JSX.
Your example template and the others here are almost jsx after it's compiled (handwritten below). This jsx discussion seems more about removing the compile step, which you can do with https://github.com/developit/htm
fwiw I think this is worse than Marko in terms of syntax and certainly in terms of readability. For all its flaws, HTML / XML / like syntax is such a good declarative way of writing UI imo. React would not be as popular as it is today were it not for JSX. Like the other reply to your comment said: this is effectively identical to what JSX compiles to assuming your jsxPragma is `m`
I mean, you’re technically correct. But you’re also not understanding the point.
What people mean when they say “React is just JavaScript” is…
1) JSX, more than any other templating system, is just HTML interleaved with JavaScript. It’s HTML, and anything between { and } is evaluated as JavaScript.
2) Inserting a React component’s “HTML tag” in your JSX is _actually_ the same as calling the JavaScript function. The HTML attributes are the function arguments. Yes, inside your function there can be state, and there can be contexts, and there are refs. But you get at all of those things by calling JavaScript functions.
Like,
<b><MyComponent attr=“yes” /></b>
is literally identical to:
<b>{MyComponent({ attr: “yes” })}</b>
It’s the tiniest bit of syntactic sugar.
I feel like too many people think “React is Just JavaScript” is some kind of lie people tell to make React sound cool.
It’s not a lie. There’s a _small_ amount of hand waving around the word “just” but the point is, it’s WAY smaller than what you need to explain the ways Svelte or Vue or Angular diverge from plain JavaScript.
It's further than that even. JSX has the semantics of (modulo a couple of optimisations there and there) a bunch of nested function calls returning normal JavaScript objects. That means you can, in your head, very easily convert between the JSX representation of an expression and the equivalent transpiled JavaScript code.
This is unlike a lot of other templating languages where, even if the expression part of the language is pure JavaScript (or PHP or Python or whatever), it's still interleaved with arbitrary text which will get printed out according to its own rules. This makes the whole thing much harder to reason about (leading to the philosophy that you should put as little logic as possible in your templates because it makes them harder to understand, _even when that logic is directly related to the templating process_.
A good example is for-loops. In a lot of templating languages, you start in text-land, then you enter expression-land to write the opening {% for (const X of ...) %} line, then you're back in text-land again. You sprinkle in a couple of expressions, and then at the end you go back to expression-land to close the loop. You're jumping backwards and forwards between the two worlds, but there's no real syntactical or structural support for mixing them.
Meanwhile, in JSX, you start in text-land, then you open up an expression between two curly braces, and in that expression you write the entirety of your loop. If you need to go back to text-land within that loop, you can create a _new_ set of text nodes, but you're not interleaving expressions and text in the same way.
The result of this is that, once you understand how your JSX will get compiled, it's very easy to read it as if it were the JavaScript that it will get compiled to, rather than as a separate templating language. Which in turn makes it very easy to think of it as "just JavaScript", even if it's technically a syntax extension.
I don't think the syntactic sugar works how you describe. JSX components actually desugar to something like:
<b>{jsx(MyComponent, { attr: "yes" })</b>
(Previously this function was called "React.createElement", but these days they have special functions that only the JSX compiler is allowed to use.) The extra layer of indirection is needed to do things like support hooks being called inside of MyComponent's function body, keep track of `key` props, and so on.
Yeah I don't think you ever could just call MyComponent(props) directly if the component used hooks. If it was hookless (what a concept...) it wouldn't matter.
> JSX, more than any other templating system, is just HTML interleaved with JavaScript. It’s HTML, and anything between { and } is evaluated as JavaScript.
That’s not true though and IMO is one of the weaknesses of JSX: it looks like something it is not. Having to use className instead of class is one of the most obvious tells. But in theory if it was just HTML with {}s I should be able to do:
and many other things you’re actually not able to do. Not to mention that things like onClick aren’t actually HTML attributes and are instead event listeners, etc etc.
Once you grasp that what you’re actually doing is a function call with an object of arguments it makes sense. But it isn’t HTML. It’s a chain of function calls.
We’re all really used to it so we don’t think about it a lot. But I always try to remind myself of that when I look at a new unfamiliar syntax.
(not to mention, your example isn’t correct! <Component/> don’t map to Component(), it maps to previouslyUnknownFunction(Component()), which is another confusing factor)
You can use React with just JS, JSX isn't core to React. htm is a library that uses string templates and is just Javascript but works like JSX and can (but doesn't need to be) compiled down like it, and you can use with with React or other tooling.
I’ve never been a fan of JSX. I tried years ago and wasn’t super into it, and then Vue after that and found the syntax a lot easier on the mental model.
Generally for templating, you want a visual distinction between the control language and the target/rendered language, because they are two different things.
Where they aren't two different things, you have some kind of component configuration language, like WPF on .NET. There is no control language, the instantiated components have behaviours and are responsible for any control logic, like rendering a list of items. This isn't a template language though.
HTML now has web components and so you can think of it in the latter way. I'm not sure if anyone has take this approach though.
> Generally for templating, you want a visual distinction between the control language and the target/rendered language, because they are two different things.
But as I just said, in the end their function actually doesn't seem overly different (to me at least) so a visual distinction with curly brackets rather than angle brackets is perhaps not necessary.
Languages are intended to be read more than written. You'll often be manually reading both the original source and the generated source and comparing them to ensure the original source is being correctly interpreted. Having those visual markers is very useful for debugging this process.
The question is why developers even want to contaminate markup with programming constructs when they have already everything they could ask for, including an object literal syntax ("JSON") for arbitrary graphs that also can encode a DOM.
SGML (XML, HTML) is for content (text) authors not developers, but webdevs just don't get it and look at it as a solution to developer problems.
These aren't good because for 0-lists you have an empty parent containers so often you have a wrapping if outside all of that. More generally, template logic indent doubles up inside the indent levels of the template markup and I just find it ugly.
I like vue a lot more;
<ul v-if={users}>
<li v-for={some in users}>{some.name}
</ul>
To each their own. This syntax actially resonates with some people, which is why template-based frameworks like Vue and Svelte are also popular. In fact, at first glance this reminds me a lot Vue in some of its approach and syntax.
BTW - with Vue you can use entirely JSX of you dislike HTML component syntax (I don’t know enough about Svelte to know if it allows the same).
React has not been just JavaScript for a long time. The react DSL just keeps getting more and more bloated as they add more hooks for more and more edge cases (useFormStatus, useActionState, etc…). It’s becoming just another bloated mess now. And I used to love react!
This looks promising though. The syntax looks very straightforward. Even though it’s not “just JavaScript” it is very easily understood by most programmers. I’ve glanced at it for all of 2 minutes and it all makes perfect sense. Functions look like functions. Variables look like variables.
I think it looks cool!
It was my reason for switching to React when I learned TypeScript after getting more into JS frameworks via Vue.JS.
My starting point was Vue 2.7, and I started out using string templates haha :)
Even wrote some reactive custom code (without Vue, just regular DOM code) in a customer widget that utilized Object.defineProperty et al, inspired by Vue.
And today, while I'm using React at $job, I also think Vue 3 is probably a solid framework as well.
Last time I checked, they improved on DX of their component and templating system. But I'm not even sure whether they still recommend the v-if etc helper tags.
For what it's worth, even Vue 2 always also supported JSX and later TSX
React is "just JavaScript" that you have to write in a very particular way, which the language in no way helps you enforce, for otherwise your "web app" will misbehave is bizarre and confusing ways.
React is not the same thing as JSX. You can use React without using JSX and you can also use JSX without using React. This argument makes no sense from the get go.
I mean it's a case of use the right tool for the job.
For consumer, it's overkill.
For pro-sumer, it's perfect, imo. You can start pushing the boundaries, here, but most will not for residential. If you are pushing the boundaries, you are probably savvy enough to roll your own solution or get into the actual, hard-core enterprise stuff.
For small businesses, it's similar to pro-sumer.
For enterprise, use something else.
But honestly, you could make it work for any of these, 99% of the time.
I fall squarely into pro-sumer and my setup has been flawless for me. It's got all the bells and whistles I could ever need while not being too overkill nor really that expensive in the grand scheme of things. I am planning on switching over from Synology to a UNAS for the integration with Identity.
It sounds like you are the exception for pro-sumer.
Unifi is what you swap over to once your time becomes more scarce and money more plentiful. At least in all the cases of my peer group.
It's far less customizable, and can be maddening sometimes if it doesn't Just Work(tm) - debugging it can be a giant pain. You will also be paying the Ubiquiti tax.
I simply redesigned my overly complex home network to be much more boring, and am okay with that. I don't want to tinker with my home IT stuff much these days - I want it to just work, and changes to be easy.
I've found Unifi Network and Unifi Protect to have come a long way in the past 3-4 years. They still drop hardware duds and software bugs here and there, but overall it's been a rather decent experience for the most part. I understand all the core level technology and configuration bits, but I simply do not have the desire to ssh into switches or whatever to configure a new port these days. Then open source NVR story is also just horrible even today.
It's also great for remote installs for other non-technical people/orgs I help out with. One dashboard I can just click on and go take a look to figure out whatever problem they may be having. And a new setup takes hours vs. days.
That your network stack and your nvr stack was the same thing (and fully local) was a huge selling point for me. If you are only interested in network, you could probably get more customizable/hackable or cheaper (or both) alternatives.
I do not know of an alternative stack that does everything like Unifi.
I've found the same. I've moved from a homebrew tinkerer's delight home network with pfSense running in a VM, Supermicro FreeBSD ZFS fileserver, hodgepodge of cameras etc. to a top-to-bottom Unifi Stack.
My time is worth a lot more now, my family appreciates very much that it "Just Works" (tm), and -- most importantly -- the cognitive load for me is a fraction of before.
I’m sort of all for not wanting to spend much time fiddling with my home network, but the issue for me that UniFi doesn’t actually Just Work. It’s too buggy.
I choose to believe you but your experience and mine are apparently VASTLY different. I would even say I'm on the complicated side of pro-sumer in terms of my network. That is to say it's surprising and I think you might just be unlucky.
Use NextJS, then. I think everyone in this thread and the author of the post is intentionally choosing sub-optimal setups for the side they don't like.
For $500+ you can get a really, REALLY nice Damascus steel chef's knife with a beautiful patina and wood handle. Yes: it requires a bit more maintainable but nice things often require some work. When it's properly honed & sharpened, it'll cut just as well as this.
So you're basically saying that you can spend as much money to get a knife that will cut as well but requires regular work put into it, whereas this doesn't? I think that's the whole pitch here...
One of the most frustrating parts about "AI" in its current form is that you can challenge it on anything and it play dumb, being like " oops I'm sowwy I was wrong, you're right"
I wish it would either: grow a spine and double down (in the cases that it's right or partially right) or simply admit when something is beyond its capability instead of guessing or this like low-percentage Markov chain continuation.
I was once in an argument with Claude over a bug we were trying to identify in my code, and it refused to concede my argument for almost 20 minutes. It turned out to be correct, and boy was I glad it didn’t capitulate (as it often does).
I came up with a prompt that actually reproduces this behavior more reliably than any other I’ve tried:
”When presented with questions or choices, treat them as genuine requests for analysis. Always evaluate trade-offs on their merits, never try to guess what answer the user wants.
Focus on: What does the evidence suggest? What are the trade-offs? What is truly optimal in this context given the user's ultimate goals?
Avoid: Pattern matching question phrasing to assumed preferences, reflexive agreement, reflexive disagreement, or hedging that avoids taking a position when one is warranted by the evidence.”
reply