Let me take a stab at explaining how AlpineJS is different. First, let me talk about the two "modes" of front-end frameworks, what I'll call: "FPC" and "Sprinkled":
FPC or Full Page Components: the original HTML source (as seen from "view page source", not "inspect") usually contains a tag like `<div id="app"></div>` which simply serves as the place where the FPC-oriented framework inserts its magic. All the magic happens in the JS (possibly generated by compiling from something else like JSX or a component DSL). Note that a FPC is not necessarily a SPA; you could have multiple pages with one FPC each.
Sprinkled: the original HTML source has the framework's tags, attributes, and/or other markup sprinkled throughout it. The framework will search for these sprinklings in the original HTML and do as they direct. Usually the framework only looks within an encapsulating tag so the original HTML might have something like `<div id="app">...more HTML with sprinklies...</div>`.
React and Svelte are FPC frameworks. All the exciting stuff is in the code: JS, JSX, or a JS-like component DSL.
VueJS can be used in multiple modes. It can be used in pure FPC mode. It can be used in hybrid mode: with both components and sprinklies in the original HTML, including sprinklies between a component's start and end tag. And it can (almost) be used in pure sprinkled-mode. I say "almost" because you do need some JS code to define the mount point and the data. (VueJS also has two sub-modes for components: compiled client-side and pre-compiled during the build. The later requires a more complex build step).
AlpineJS is (mostly) for pure sprinkled-mode. It is easy to write non-trivial function with no JS at all, other than loading AlpineJS itself from a CDN. On page load, AlpineJS will automatically do the needful; no bootstrapping JS is required. When re-use and/or complexity requires it, you can move some or much of the code from HTML to your JS. For even more complex stuff, the new plugin ability in V3 of AlpineJS makes adding your own directives/attributes or magic variables/functions easy. This extra ability in V3 just means although you can do 80% with no or very little JS, you still have room to grow for the other 18-20%.
AlpineJS is great for and focuses on the needs of simpler apps. And most of the apps we develop should ... be ... SIMPLE.
I can see how Alpine makes some extremely simple things simpler than React, but it also really seems to restrict me in how I can refactor my website or app. With React I can keep things almost as simple as with Alpine, or move to more integrated solutions (e.g. SSR with hydration) without rewriting much of my existing code. Alpine basically has me stuck with only client side rendering without a lot of optimizations.
The only downside I see is that, unlike with Alpine, a build step is mandatory. However, I assume that any real production Alpine app will also want to include a build step, if only to decrease bundle size. It's such a low-hanging fruit and improves the experience for basically any user.
I get why Alpine is interesting from an idealistic view of avoiding complexity, but React+JSX just seems much more pragmatic to me.
FPC doesn't sound right since you can have a react component for just a single part of a page, it doesn't necessarily need to take control of the whole page.
Yes of course the components are usually not the entire page; don't take the terms too literally. I'm still searching for the best name for these modes ("sprinkled" isn't quite right either). Although "full body component" or "big section component" might be a little better, I suggestion not missing the underlying idea or point due to imperfect terms.
Very true, and is a highly useful tool to add interactive content to a section of an MPA - React used in this way, without requiring a state library and everything else is actually quite nice to work with.
The website being announced in this post, alpinejs.dev, is new for V3 of AlpineJS which was launched just yesterday. I've been using it since V1 and I can say it doesn't just look like but really is a perfect balance for projects too small for Vue or React but to big for VanillaJS. I would also argue that small and simple is better for most websites.
I agree with you on the distinction but violently disagree on the conclusion. With UBI you still pay for things and the capitalist system still functions; it just lifts a baseline for all of society.
At a previous job I was at, we put each release of the sprocs into a different schema. Upgraded app servers called sprocs in schema "r102" while the not-yet-upgraded app servers continued to call sprocs in schema "r101" until they were eventually upgraded.
IMHO, the biggest RTFM-Fail ever is related to ASCII. Think of all the errors made and time lost fixing issues with CSV (comma separated value) or TSV (tab separated files) or pipe-delimited fields in records, etc, etc due to having to handle the case where the delimiter character is not a delimiter character but valid data with a field.
ASCII provided characters specifically for this purpose. But no one seems to have RTFMed. ASCII 31 is a "unit separator" (or field separator as we'd call it today) and ASCII 30 is a record separator. There's even ASCII 29, a group separator, so you can have a set of records related as a group (for example, a group of records of different type but related to a single customer). And there's ASCII 28, a file separator, so you can have multiple "logical" files within one physical file.
I think that's the unfortunate consequence of people without a basic CS background inventing ad-hoc data formats. I recently had to deal with a kind of "nested CSV", where each level of nesting introduced a new delimiter! Who needs recursion?
Escaping drastically complicates parsing (though not as much as quoting, thank god). But you seldom need to nest tables within tables. Much more frequently, table values want to contain embedded newlines.
A general-purpose parser has to be able to handle the possibility of nested tables, so it has to account for escaping. And once you have an escaping-aware parser the choice of delimiter is no longer critical.
Escaping is an unnecessary kludge in 99% of cases. If you need nested tables, then you need a special-purpose format that allows for it--and it will very likely look more like a binary filesystem than a parseable text file. If you don't need nested tables, then escaping is unnecessary if the format uses delimiters which aren't present in the data. A lot of data includes newlines, some data includes tab characters, but only binary data would ever include the ASCII specified delimiters.
Don't get caught in the CS trap of thinking you need a completely "general purpose" parser, when a slightly-less-than-completely-general parser will be significantly easier to write, simpler to understand and debug, and faster to execute. And as mentioned above, if you do find yourself needing more than this parser, then you should be looking at non-parsing based approaches anyway.
Luckily people who designed programming languages had a better idea: introducing some begin and end markers can allow nesting without escaping them. Here I have two blocks nested inside of the outer block but I don't have to escape anything: { { } { } }
Some financial protocols use those in anger still. Credit card auths and such. There were some serial things that used them as intended too, transfer protocols etc.
iirc "Relia COBOL" back in the early days of DOS also had a format that used the delimiters and all properly; but then did goofy things like globally translating "'" (apostrophe) to "*" (asterisk) anyway.
FYI, the IBM S/360 did support ASCII[0]. A bit in the program status word indicated if the machine was running in ASCII or EBCDIC mode. Most customers ran EBCDIC because it was more compatible with their masses of punch card originated data (no translation required). For the S/370, for virtual memory, a bit in the program status word was needed to indicate addresses were real or virtual. IBM surveyed its customers and found almost no one was using ASCII so its bit was taken for virtual memory.
I would "Join the wait list" but it just opens a page with something my browser blocks immediately because it side-loads some frame from google.
A simple HTML form to summit an email really cant be that hard that it needs to be outsourced to google.
Apologies. Launched just 2 days ago as a static site on Netlify. Will add a JAMstack-based form once our api backend server is up and running. Google Forms was a quick and dirty solution that let us deploy something now. Fossil on HN is rare so I prematurely jumped at the chance of a mention.
FPC or Full Page Components: the original HTML source (as seen from "view page source", not "inspect") usually contains a tag like `<div id="app"></div>` which simply serves as the place where the FPC-oriented framework inserts its magic. All the magic happens in the JS (possibly generated by compiling from something else like JSX or a component DSL). Note that a FPC is not necessarily a SPA; you could have multiple pages with one FPC each.
Sprinkled: the original HTML source has the framework's tags, attributes, and/or other markup sprinkled throughout it. The framework will search for these sprinklings in the original HTML and do as they direct. Usually the framework only looks within an encapsulating tag so the original HTML might have something like `<div id="app">...more HTML with sprinklies...</div>`.
React and Svelte are FPC frameworks. All the exciting stuff is in the code: JS, JSX, or a JS-like component DSL.
VueJS can be used in multiple modes. It can be used in pure FPC mode. It can be used in hybrid mode: with both components and sprinklies in the original HTML, including sprinklies between a component's start and end tag. And it can (almost) be used in pure sprinkled-mode. I say "almost" because you do need some JS code to define the mount point and the data. (VueJS also has two sub-modes for components: compiled client-side and pre-compiled during the build. The later requires a more complex build step).
AlpineJS is (mostly) for pure sprinkled-mode. It is easy to write non-trivial function with no JS at all, other than loading AlpineJS itself from a CDN. On page load, AlpineJS will automatically do the needful; no bootstrapping JS is required. When re-use and/or complexity requires it, you can move some or much of the code from HTML to your JS. For even more complex stuff, the new plugin ability in V3 of AlpineJS makes adding your own directives/attributes or magic variables/functions easy. This extra ability in V3 just means although you can do 80% with no or very little JS, you still have room to grow for the other 18-20%.
AlpineJS is great for and focuses on the needs of simpler apps. And most of the apps we develop should ... be ... SIMPLE.