111 karma · joined June 27, 2022
In any case, if you sum a list of numbers you have to look at each value. There’s no way around it. You can parallelize, like MapReduce, but the number of items is unchanged. You can preaggregate, but at some point you need partial sums.
And yes, Deno is just one player in edge, but you can agree there is much more money involved with all those other players you listed.
It’s going to be a battle of eyeballs from those edge providers then wouldn’t it? Whether that’s consulting or licensing fees, or just an acquisition / acquihire player.
Maybe you’re suggesting these players would build a runtime themselves. From my experience, only a fraction of companies, rarely, tackle ambitious projects like this. It’d be hard to justify to management who need quarterly results. Instead, they’ll fork an existing technology and make it better, because you can show incremental progress but keep your baseline. For example, Facebook didn’t rewrite their PHP code right away. They wrote a faster interpreter.
This part, very early on in the Bun page, stood out. That’s a monetizable product, even if the code is open source. That to me felt like positioning itself as a potential drop in replacement for Deno Deploy / Edge Functions.
There was serverless, and now the next trend is with edge computing. It’s already happening, but now specifically about runtimes on that edge.
Maybe you can’t falsify this, but it’s a question of risk vs reward.
It’s currently at 0.1 release. Chances are it has a much higher chance of breaking. And when that happens, it would likely take occupy way more time to debug than the hundreds of ms saved.
Also by being new, it means it has not had a chance to cover all the cases yet. That’s the devil. It’s fast now, but it’s an apples to orange comparison until Bun is at a stable release.
The fact that this project uses Zig suggests to me the developer is talented , passionate, and willing to challenge the status quo.
When you choose a lesser known language like that to tackle a hard problem, chances are you are confident in yourself and the language.
The problems I pointed out with the JavaScript ecosystem as a whole is that it’s low hanging fruit. It’s not that there aren’t financial opportunities elsewhere, outside JavaScript. There definitely is. But the perception of financial incentives is the low hanging fruit, plus high reward.
In this case, it will boil down to how much Bun innovates versus just being a thin wrapped around existing solutions. And again, I don’t doubt this. Skeptical, in general, but not ruling Bun out.
I don’t intend this as a knock on this project. Competition is good and, this space, unlike the rest of JavaScript, could do with more players. There are some promising numbers and claims here. I hope it works out.
I’m genuinely posing this intellectual question of financial incentive as an theory for JavaScript fatigue as a whole.
High profile threads on JavaScript fatigue trend on HackerNews multiple times a week. The wide range of theories about why web developers reinvent the wheel strangely leave out the financial incentives.
Everyone claims their framework is the fast, powerful, light, batteries included, modern, retro futuristic, extensible, opinionated, configurable, zero config, minimal (3kb, gzipped minified, of course ). The list goes on. A few days ago, I was chatting with someone how all these JavaScript libraries make these words have no meaning. To demonstrate, I screenshared a bunch of landing pages. At this point, I haven’t exhaustively, in one sitting, cross referenced these landing pages. 90% of the libraries shared the same layout. 3 columns / cards with one of those hyperbolic words.
Previously I thought it was pretentious and weird that Svelte marketed itself as “cybernetically enhanced web apps”. What does that even mean? Then again, none of the descriptor words like light, dynamic, and ergonomic mean much. At least Svelte was memorable.
Occasionally, one of these libraries would describe their interface as being ergonomically designed. As if other developers designed their interfaces to not be ergonomic. It’s like how we’d all like to think we’re nice, good, decent people. The majority of people would not do bad stuff if they perceived it as such.
I do think most JavaScript developers have good intentions. Then I’ve also seen DevRel / Evangelist types who shill their library, with disingenuous benchmarks, knowing full well there are better solutions, or that they can help make existing solutions better, to everyone’s benefit. The spoils include consulting, training, speaking fees, books, swag, collecting Patreon ( there are some controversial projects which come to mind ), resume building, GitHub activity social capital ( I’ve talked to some recruiters who were fixated on the idea that you publish code on GitHub, specifically Github, because to them, VCS=Git=GitHub, or it doesn’t exist )
That’s not true. A not uncommon type of museum in Japan are the “Showa Era Museums”.
I was not alive during this era, but I feel nostalgia nonetheless. For context, these museums usually capture the 50s-70s, Japan’s rapid economic growth feeding into consumerism, or maybe the other way around, and there are record players, pachinko machines, and a very distinctive, bright, neon filled aesthetic.
Modern Browsers sanitize punycode, not so sure about bespoke browsers that live inside other mobile apps
Isn’t that why Disney acquired Star Wars and Marvel?
Imagine an Amazon theme park alongside Universal Studios and Disneyland.
People in developing countries just hand carry a tank.
You can also position yourself to be an acquisition target.
Does anyone have insight into why? Parcel apparently rewrote in Rust, but I guess that's not necessarily the bottleneck here?
Sure, then the backend can expose a gRPC / protobuf interface instead. Mobile apps can readily deserialize this and it will be more performant, both in network bandwidth and data parsing, too, especially with first-party to first-party SDKs. It's strongly typed and serves as a better data contract language than both HTML and JSON. JSON is loosey goosey because of JavaScript.
Then the frontend server now plays the role of aggregating data from gRPC backends and converting it to HTML.
The gravitation to JSON is a case of web developer familiarity.
Which is what PHP was built for.
> If people could try to understand SSR before diminishing it, we could have much more productive discussions.
If new generation of frontend people could try to understand PHP before diminishing it, we could have much more productive discussions.
Makefile and sed are decades old, stable, available on every Linux distro including the Alpine docker image clocking in at 30mb total. The entire image containing an Linux distro with all the needed CLI tools is 30mb.
└─ ▶ podman build -t base . && podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
localhost/base latest b593261330c1 1 minutes ago 30.5 MB
The only dependency here is the Go based minifier, and Go programs are self-contained executables.Alpine contains an entire package manager. Compare with adding Node and one CLI for minification.
└─ ▶ echo 'RUN apk add npm' >> Containerfile && echo 'RUN npm i -g terser' >> Containerfile && podman build -t node . && podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
localhost/node latest a28f38037137 6 seconds ago 93.5 MB
localhost/base latest b593261330c1 5 minutes ago 30.5 MB
Assuming dependency management was equal level of maintenance with Node, the spirit of Node ecosystem tends accept being whimsical with breaking changes. Terser or whatever Node-based processing library will introduce breaking changes to their config in relatively small timescales ( months, years, instead of decades ). That's not inherently a technical fault of the ecosystem as it is a cultural one. The popularity of JavaScript is its own undoing. Opting for tools in other web-friendly languages selects for a different type of developer.That's just for minification. Want to inline CSS? That sed command is 66 characters long. That's about the same as Parcel's zero-config config boilerplate that is NoOp: https://parceljs.org/features/plugins/. Surely a WebPack config is more than 66 bytes. I proceeded to add Parcel to compare how much it increases the image size, unfortunately it failed because there is a Python dependency:
└─ ▶ echo 'RUN npm i parcel' >> Containerfile && podman build -t parcel .
[2/2] STEP 18/18: RUN npm i parcel
npm WARN deprecated stable@0.1.8: Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility
npm ERR! code 1
npm ERR! path /usr/share/nginx/html/node_modules/@parcel/watcher
npm ERR! command failed
npm ERR! command sh -c node-gyp-build
npm ERR! gyp info it worked if it ends with ok
npm ERR! gyp info using node-gyp@9.0.0
npm ERR! gyp info using node@18.2.0 | linux | arm64
npm ERR! gyp ERR! find Python
Fine, I added Python, Make, and other transitive dependencies to see how deep this rabbit hole goes: └─ ▶ podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
localhost/python latest 05582c8b2425 2 minutes ago 156 MB
Will Parcel installation work now? Nope, here's the new error trace: https://gitlab.com/-/snippets/2364041.
It appears this is a dependency issue with Parcel, Maybe?, with this similar 6 week old thread: https://github.com/parcel-bundler/parcel/issues/8152, which reiterates the painpoint about Node.Let's take a step back and forget the Parcel example for a second. How about NextJS? From that 30mb Alpine base image:
```Containerfile
RUN apk add npm && npm i next react react-dom
└─ ▶ podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
localhost/nextjs latest d177ee032ff0 9 seconds ago 266 MB
Kudos to NextJS for installing properly at least, but that single command added 266-30mb = 236MB to the image, and this is where the bloat creeps in. Thinking 200MB is a nothingburger is how we end up with gigabytes large images. <img src="my_cat.jpg" alt="My cat" onclick="this.src = 'my_other_cat.jpg'">I don't see this design pattern as forcing a particular back-end framework?
It's merely shifting the frontend<-->backend contract from JSON to HTML.
Some backend engineers arguably would prefer HTML. Especially if their backends weren't Node. Backends were originally C servers that sent a string of HTML back. I think backend engineers are fully capable of "juggling" with this new/old paradigm.
Some projects claim they are "zero dependencies" but a few sentences into the readme and you see an `npm install` and now you notice there is `package.json` after all . They meant zero runtime dependencies, which is still praiseworthy, but not zero `devDependencies`.
For my greenfield web app, I attempted to have zero dev dependencies on Node. I wrote some vanilla HTML, JS, CSS, and now needed to reduce network transfer. Requirements:
- minify
- inlining CSS file into HTML
- compress with Brotli
- print out final byte size
- nice to have: run a dev server that serves static Brotli
We know the story with WebPack. I looked to Parcel instead because it's the "zero-config" tool. It was promising because it inlined my `@import css` into my HTML, and logged out the filesize. The watch and reload feature wasn't working as promised, but that was nice to have anyways. For Brotli compression, which is mainstream at this point, I quickly needed to add a `.parcelrc` config. Their code sample didn't work because it turns out that in the real world you need to make your .parcelrc extend/inherit "@parcel/config-default". Parcel stopped logging at the compressed file sizes and not the final Brotli file sizes. Finally, Parcel's dev server is useless to me because you can't set encoding headers for "Brotli" files so the browser just attempts to download it. I didn't have a .gitignore file, and adding this one Node dependency on Parcel added 3,000 new files. To be fair, that's miniscule for a Node project.
I asked myself if I can achieve the same results with CLI tools that are not Node. I first looked to the Golang ecosystem. I stumbled upon https://github.com/tdewolff/minify. It just does minification. It's comparable in output size to other Node minifiers, but faster and just works. The lexer code is very readable, even for me who is not a compiler or systems expert. It's one command to install the CLI, and one command to Minify. You can do `npm install global -g` to get CLIs, but Node supply chains tend to be much deeper.
This bespoke one-liner does the CSS inlining for me:
RUN sed -i "s/@import \"style.css\"/$(cat style.css)/g" index.html`
For Brotli compression, I went with the official first party CLI ( also Go based ) instead of using a third-party wrapper like you'd have to do with JavaScript.One thing I was missing in NPM scripts as a self-documenting way of describing what commands to build, run, test. I've seen cases where people are beholden to a `package.json`, sometimes when their project doesn't even involve JavaScript. When you have a hammer, everything looks like a nail. It turns out Makefiles are a better way of doing this, especially if you don't already have a active relationship with Node
.PHONY: help
help: ## This help.
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
# DOCKER TASKS
build: ## Build the container
podman build -t ${APP_NAME} .
run: ## Run container on port configured in `config.env`
podman run -it --rm -d --env-file=./config.env -
p=$(HOST_PORT):80 --name="$(APP_NAME)"
It's even better than self-documentation, because the documentation is self-documenting: $ make help
help This help.
build Build the container
run Run container on port
configured in `config.env`