You're authoring in TSX and serving JS to browsers, so there's clearly a build step. How is your model different from e.g. vite serve?
How does it get deployed? Are the files translated to vanilla JS on request, or are they translated ahead of time and cached (in other words, a build step)?
Not having all the code in-line that can be in-line is like the 90s. You had me until the 'no bundling' thing. Separate http requests for all resources is a non-starter for anyone worried about page speed. I do like the choice of Preact though!
I take the opposite approach - bundling is a non-starter for me. But it really depends on what you're building. Bundling can be great for web apps, but for content-driven websites where SEO optimization is key, I prefer the "90s-style" approach and Fullsoak's philosophy.
Also, separate HTTP requests allow for granular caching, and with HTTP/2 the overhead is minimal.
You're doing the opposite of SEO optimization if page speed score is of any value to your SEO (and it's important to Google's SEO ranking, so yeah). I work on a "content-driven website" - actually a few thousand of them - and our clients definitely want their SEO to be top-notch and page speed score factors into that. Any http requests for external resources will bring page speed down, and that can affect SEO. I don't have to worry about caching at all when the pages are scoring perfect 100% on Lighthouse.
and that's a totally valid concern :) So far I only wish to check the concept in general (ie: "does it work"). As for "does it work fast / at scale", definitely a future topic.
So it can be just 1 HTML resource + 1 js file for every unique path.
And with preact-iso (or react router) we can make subsequent pages load on-the-fly without a hard browser refresh / hard resource reload. Like so: https://github.com/fullsoak/bun-examples/blob/main/src/compo...
But ultimately: I do see rooms for improvements re. resource optimizations. My personal wish is to use standard web specs such as "preload", "prefetch", "server push", etc. to optimize as much as possible, without taking the "bundling route" - so: just exploring a different taste, not that I have anything against the existing "build routes" :)
Deno does not support jsx and typescript 'without a build step'. It just runs a build/transform step for you under the hood - using the same tsc compiler, config, etc.
> a shell script that builds and runs a C program from source has no build step
I would say so. Ultimately build step or not isn't a meaningful thing to care about. What matters is the cold start/runtime impact. In the case of deno/bun, the impact seem minuscule/not meaningful.
Browsers cannot parse jsx/tsx natively. Deno is transforming the code you write before it is executed in the browser. That transformation is typically referred to as a build step.
I'm well aware that browsers don't run TS. But in this instance we are talking about the server side runtime.
Building is creating the runnable artefact, but in the context of the server this artefact is already runnable, so I'd just call that "interpreting" the program
> But in this instance we are talking about the server side runtime.
Not at all. We are talking about SSR, and the need for a build step (on the backend). That should be pretty obvious considering the explicit mentions of running the code in the browser, jsx, ts, etc. (Not to mention the backend runtime cannot run typescript/jsx without build either)
> Building is creating the runnable artefact
That's not all that 'building' is...
> but in the context of the server this artefact is already runnable
No it's not. The JIT/interpreter within Deno cannot run this code without doing a build first. This is made very obvious and explicit in the Deno docs.
my apologies for using controversial wording. I'd love to confirm that we still must have some sort of transpilation / transformation because no Web Browser can consume JSX code directly (after all, JSX is just syntactic sugar, not a base language).
I would probably replace a lot of this language with something along the lines of "powered by Deno, enabling simplified, all-in-one tooling." You don't want it to look like you're taking credit for the features that Deno is responsible for. Would also help me understand what your project offers vs what Deno offers.
that's a nice perspective :) I totally had no intention for 'taking credits' as I assumed it's a 'given' that we run TS directly with Deno, Bun, or Node.js with the experimental flag.
I'll take this to my desk & update the wordings towards your suggestions above - thank you!
Thanks for your thoughts! I do adore Fresh. In fact, I have run production projects on Next.js and Remix, and played around with Deno Fresh, and I enjoy them in different ways.
When I wrote "no build", I simply meant that we do not bundle the whole app into a single file.
Thanks for the reply! I don't quite understand why you want to avoid a build step. Normally when people talk about that what they really mean is they don't want to have to run a build command, but you still have that.
To put it another way, what is the downside of Fresh's build step that you avoid?
Ah please don't get me wrong, there's no build command in my example. The command to start the app directly is: `deno src/main.ts`
and `main.ts` is an original source file, it's not a "bundle" of many files together, like in other setups with build config (tsconfig, webpack config, babel config, etc.)
Imo, Fresh' build config is already way simpler than the "traditional" webpack approach (https://deno.com/blog/node-config-hell). Here in FullSoak, I only wish to push this boundary further ie. "no build config at all".
> The difference is that the precompile transform analyses your JSX statically and stores precompiled HTML strings if possible. That way a lot of time creating JSX objects can be avoided.
So if there are compilation errors, who is stopping me from running without the build?
Hi! My apologies if the wording was confusing :( By "no build" I mostly meant "no bundling" (so: we're not combining all files into a single js bundle entry).
I've been wanting to make a no-build webapp using Mithril.js[1][2], with plain-JS type annotations that don't require build steps (TypeScript's JSDoc syntax [3], but I'm looking forward to the proposed type annotations[4]). With something like this, type-checking would still require running a command when using Node.js, but it's just an optional developer dependency since the code would still be just standard JavaScript.
But in the end I've not done that because I figured it's more effort than it's worth, compared to just doing server-side rendering with other backend languages and just using JS where needed (not necessarily "raw" JS, I just mean it as in "not having a full-page component").
I'm just letting you know that there are definitely some people like me that would like if more JS tooling didn't require a build step or specific runtimes (like Deno or Bun) as a hard dependency.
kudos to the MithrilJS project & also for having earned visibility on OpenCollective <3 I can see the (much respected) history track of this project.
Having "survived" the "Internet Explorer ages" of the www, I can share that my heart always has a slot for "vanilla JS" (& anything towards its direction). When coding solo and/or for light-weight (enough) projects, I also tended to do pure JS.
This looks great. I would love to see something like this evolve to become the industry standard.
My only worry between then and now is will it run into a wall if it is unable to solve problems that build steps did?
Does it handle extensions that webpack did browser shims? I assume those will just be imported modules.
And of course it is a new-thing-to-learn(tm) which is always a tough sell to getting it used in a corporate setting. For good reason.
Here's some things I like about the idea, mostly duplicating what you said already:
1. By holding your project to a no-build constraint, that means we won't go down the rabbit hole of toolchains like we did with bower, webpack, etc. to fix any problem. Ever. Yay!
2. You really did simplify the "build" step. My personal experience has been that that has always been a source of frustration, especially since most developers just want to get-shit-done and the more deep-diving devs would have to martyr themselves to get it working again. Now hopefully they just need to understand one set of config to tweak to get the application working as is.
3. It feels to me like your project will own any breaking issues that come out of it. It's always been a pain when there was complexities at the edges of parts of the toolchain. If NPM v16 breaks with webpack v5 or whatever its version scheme is, one or the other needed to upgrade to fix it and the ownership of the issue wasn't always clear. Sometimes it would take awhile because of a niche interaction between the two. And of course upgrading past it had other painful breaking changes your legacy app needed to address.
Anyways, looks good! Keep it up & good luck! I'm curious to see where this goes.
You're absolutely correct at the "problems that build steps do". One example is the whole loader stuff (e.g. SCSS, Less, and the plethora of other things we can "just import (tm)" into our TSX components). For now it was a conscious decision that I keep things "stupid simple" as I shared in a Bsky post: https://bsky.app/profile/mrkha.ng/post/3lg3qw377ss27
Re. the "selling" part, it's also my wish to see how people resonate with this. Maybe not the framework itself, but only the concept of using standard specs (ie importmap + TypeScript runtime) - & since it's just bare standards, let's see if it attracts frictions (or not).
Not sure if it's better than a Discord or sth like Tulips chat, but imho it doesn't matter, as long as there's a safe "draft space" to jot down the thinking-out-loud process, all while getting potentially feedback & help from everyone.
My next immediate exploration goals: make this framework compatible with deployment solutions such as Cloudflare Workers and Smallweb.run - atm I can't guarantee 100% success rate, but excited to see how it turns out.
i wouldn't really introduce this as "a problem solver" :) It's more like an exploration of an alternative approach that combines base concepts such as:
But if I have to pick my brain and find a benefit that this approach brings, i guess it would be that we now avoid the entire "config hell" and cognitive load of managing build setups. This article shares some of this view: https://deno.com/blog/node-config-hell
Disclaimer: i have nothing against standard build processes that we've used for years. I've juggled a lot with browserify, webpack, and their successors & siblings. I just feel it's worthy to give a spotlight for an approach where we completely go without them :)
I like it! I spun up a little remixable Glitch project based on your demo so that I could play with it in a web editor. Thanks for sharing. https://glitch.com/~fullsoak
Hi! Kudos for the work on SmallWeb. I actually attempted to run this on your platform as well. I was able to run it partially on Cloudflare workers, so I trust it's compatible with environments like SmallWeb as well. Let's see!
Hi, I just wish to update that: since fullsoak@v0.9.0, support for Cloudflare Workers has been added in experimental mode :)
Enabling this on Cloudflare Workers has been a rather challenging journey, due to the fact that the file-system APIs (that FullSoak uses) are not available on Cloudflare Workers. In fact there are still some bugs to squash, but I'm excited to share an early PoC: https://github.com/fullsoak/cloudflare-workers-examples
no I had completely no idea. Is this a generation gap thing, or maybe I just lived under a rock for too long - thank you for the heads up haha. If this causes too much friction, for sure it should be renamed..
morman teenagers do 'soaking' because they were told active participation in pre-marital sex like thrusting is taboo while soaking inside… resisting the urge to thrust… satisfies the condition
the lore continues that third persons jump on a bed they're all on is a surrogate for thrusting
wow I wasn't aware of VanJS before. It looks nice!
in my limited exploring of VanJS so far, I like that it also takes the direction to simplify things. That said, afaik VanJS simplifies the "JSX" part (so: we don't have to transpile from JSX to vanilla JS because... we don't even use JSX :D).
Can I just add to the other "words have meaning" comments?
> FullSoak is (mostly) WYSIWYG. Compared to sophisticated frameworks such as Next.js or Remix, FullSoak is actually very "stupid looking": 1) you start with a "Controller" file (as in good old "MVC") which 2) renders your TSX component as text/html content (i.e. a plain string), and then 3) the content hydrates itself on the client side.
Unless it integrates a gui page editor, it's not wysiwyg.
And hydration on the client side is very much not SSR.
Also "stupid looking" doesn't really mean "simple".
There may be something interesting here, but the naming / description is really all over the place and misleading.
Additionally, "no build" when writing typescript and jsx/tsx is not possible. The web does not have native support for these files, so by definition there must be a build step.
I think the tech here looks good, but the terminology needs a big overhaul.
thank you! You are both right that the wording could use some revamp. Perks of hacking on sth til 3am and writing a dirty README that leaves a stigma for years haha.
Also by "no build" I mostly meant "no bundling". If you look at the source code of the example deployment: https://fullsoak.onrender.com/app - you'd see that every HTML file loads a single .js file. Sometimes we can "lazy load" the entire component .tsx file (if we choose to do so).
So there's no bundling of the whole app into 1 single "entry point". From JSX/TSX to vanilla JS, we do need a "transpilation" step, and right now it's done ad-hoc (on every request). Some caching technique could be employed to make this scale & perform, but it's a topic for another day I guess.
Definitely need to find a coherent wording to describe this whole concept without causing mix up or misunderstanding. Thanks again for pointing these out!
> Even though native ESM is now widely supported, shipping unbundled ESM in production is still inefficient (even with HTTP/2) due to the additional network round trips caused by nested imports. To get the optimal loading performance in production, it is still better to bundle your code with tree-shaking, lazy-loading and common chunk splitting (for better caching).
Completely agreed! And "trade-offs" is the perfect keyword here. In exchange for zero cognitive load (ie. complexities in managing build config & consistency between dev & prod setups), we get a bunch of ESM, rendering the performance of our app dependent on browser loading optimizations (among other things).
I'll try to benchmark this "no build" setup on mdeium-large codebases, also comparing between different use cases (e.g. blog-like website vs rich-interactive web app such as "online photo editing") and let's discover the pros and cons of everything :)
Laravel and RoR are veteran giants in the Web Framework industry. I'm sure they cover "isomorphy" in their own ways, just that at the time they were born, the terms "isomorphic" and "fullstack" weren't even coiled.
This "FullSoak" framework is by no means aimed to be as full-fledged as the likes of Laravel / RoR / or even other JavaScript frameworks such as Next.js, Remix, SvelteKit, etc. - but it stays true to the "isomorphy" concept, where the same code is runnable on the browser & the server alike.
I like the no-build approach, but I'm afraid the problem is bigger.
For years, a new framework has appeared every week (it feels like every day) that promises to solve all problems with the latest buzzwords.
The mere fact that this happens shows that today's web development suffers from a plethora of unsolved fundamental problems.
Instead of fighting a problem with workarounds (and thus new problems), it would be nice if the community would sit down and ask itself how we can create a future that makes frameworks obsolete.
Sometimes I get the impression that we have more of a social problem than a technical one. If browser vendors, developers, managers, corporations, startups, freelancers and everyone else involved sat down at a table and talked constructively with each other, things would certainly be possible that would save everyone a lot of work, or am I wrong?
Remember that Dart started as an attempt to evolve web programming past some of the perceived deficiencies of JavaScript. It came out of Google, who also maintains a significant share of the web platform via Chrome. There were a bunch of snarky comments about Google trying to colonize the web and force its new language upon everyone. Fast forward a decade+: now most professional web dev is done in TypeScript, a Microsoft language that's backwards compatible with JavaScript. JavaScript itself has evolved to address some of the complaints of the past. Dart is now the VM embedded in Flutter runtime, and has sworn off ever being baked into a browser.
There are two methods that have been successful at changing the web:
- Spend countless manhours and calendar years building consensus among dozens of people through the standardization process, and hope at the end of the day that your pet proposal is one of the few that survive. There are many awesome proposals that have never made it out of committee.
or
- Build a thing that's compatible with the existing platform (e.g. React, CoffeeScript, etc.), and get a critical mass to adopt it organically, until is has the influence that the web platform will change to meet the demand.
> it would be nice if the community would sit down and ask itself how we can create a future that makes frameworks obsolete.
The community is not an entity, it can't sit down and ask itself things, new ideas appear and the good ones get adopted. You can't prevent the existence of alternative approaches and ideas.
thank you for your approval of the 'no build' approach. We don't have to necessarily discuss the "framework perspective" of this topic - this all is more like a concept, a "lego mashup" of several standards:
So even without naming a new framework, one can simply pick up the "base concepts" above and mix them together, and have something similar :)
(of course as @root_axis mentioned: sooner or later any concept materializes as a "framework" or at least a "library" - so while we unfortunately can't change the nature of society, we can actively choose what we use & what we don't use. Psss: tbh i'm not really a framework person myself haha)
I don't understand.
You're authoring in TSX and serving JS to browsers, so there's clearly a build step. How is your model different from e.g. vite serve?
How does it get deployed? Are the files translated to vanilla JS on request, or are they translated ahead of time and cached (in other words, a build step)?
My apologies if the wording made it confusing :D By "no build" I only meant "no bundling".
You can check the generated source code of the example deployment to see how it's deployed: https://fullsoak.onrender.com/
But spoiler: it's like in the 90s: each page request results in a text/html response, and the HTML doc then links in any .js or .css file it needs.
I elaborate more in this wiki: https://github.com/fullsoak/fullsoak/wiki/Concepts-&-Example...
Not having all the code in-line that can be in-line is like the 90s. You had me until the 'no bundling' thing. Separate http requests for all resources is a non-starter for anyone worried about page speed. I do like the choice of Preact though!
I take the opposite approach - bundling is a non-starter for me. But it really depends on what you're building. Bundling can be great for web apps, but for content-driven websites where SEO optimization is key, I prefer the "90s-style" approach and Fullsoak's philosophy.
Also, separate HTTP requests allow for granular caching, and with HTTP/2 the overhead is minimal.
You're doing the opposite of SEO optimization if page speed score is of any value to your SEO (and it's important to Google's SEO ranking, so yeah). I work on a "content-driven website" - actually a few thousand of them - and our clients definitely want their SEO to be top-notch and page speed score factors into that. Any http requests for external resources will bring page speed down, and that can affect SEO. I don't have to worry about caching at all when the pages are scoring perfect 100% on Lighthouse.
and that's a totally valid concern :) So far I only wish to check the concept in general (ie: "does it work"). As for "does it work fast / at scale", definitely a future topic.
I do wish to elaborate: since we use JSX/TSX, in theory we can in-line as much as we'd like. Here I include CSS in the component itself: https://github.com/fullsoak/bun-examples/blob/main/src/compo...
So it can be just 1 HTML resource + 1 js file for every unique path. And with preact-iso (or react router) we can make subsequent pages load on-the-fly without a hard browser refresh / hard resource reload. Like so: https://github.com/fullsoak/bun-examples/blob/main/src/compo...
But ultimately: I do see rooms for improvements re. resource optimizations. My personal wish is to use standard web specs such as "preload", "prefetch", "server push", etc. to optimize as much as possible, without taking the "bundling route" - so: just exploring a different taste, not that I have anything against the existing "build routes" :)
It works with bun or deno which are alternative node runtimes that support jsx and typescript without a build step.
Deno does not support jsx and typescript 'without a build step'. It just runs a build/transform step for you under the hood - using the same tsc compiler, config, etc.
https://docs.deno.com/runtime/reference/jsx/
Saying this is not a 'build step' is like saying a shell script that builds and runs a C program from source has no build step.
It has no build step. It builds when you run
It's like language implementations that nominally aren't "compiled", like Python, but nonetheless compile to bytecode when you run the program
> a shell script that builds and runs a C program from source has no build step
I would say so. Ultimately build step or not isn't a meaningful thing to care about. What matters is the cold start/runtime impact. In the case of deno/bun, the impact seem minuscule/not meaningful.
> Ultimately build step or not isn't a meaningful thing to care about. What matters is the cold start/runtime impact.
The two are closely related.
> In the case of deno/bun, the impact seem minuscule/not meaningful.
Seems like a pretty baseless assertion.
you're right, found this benchmark https://maxday.github.io/lambda-perf
So the build happens implicitly via the runtimes, then.
Bun handling the TSX at runtime is just its capabilities as an interpeter. Else we'd be saying all interpreted languages have a build step
Bun does not handle TSX at the runtime level because Bun uses JavaScriptCore as its runtime and JavaScriptCore does not support TS(X).
Bun transpiles all typescript code before executing it in the JavaScriptCore runtime. That's an implicit on-startup build step.
Browsers cannot parse jsx/tsx natively. Deno is transforming the code you write before it is executed in the browser. That transformation is typically referred to as a build step.
I'm well aware that browsers don't run TS. But in this instance we are talking about the server side runtime.
Building is creating the runnable artefact, but in the context of the server this artefact is already runnable, so I'd just call that "interpreting" the program
> But in this instance we are talking about the server side runtime.
Not at all. We are talking about SSR, and the need for a build step (on the backend). That should be pretty obvious considering the explicit mentions of running the code in the browser, jsx, ts, etc. (Not to mention the backend runtime cannot run typescript/jsx without build either)
> Building is creating the runnable artefact
That's not all that 'building' is...
> but in the context of the server this artefact is already runnable
No it's not. The JIT/interpreter within Deno cannot run this code without doing a build first. This is made very obvious and explicit in the Deno docs.
https://docs.deno.com/runtime/fundamentals/typescript/
> With its built-in TypeScript compiler, Deno will compile your TypeScript code to JavaScript with no extra config needed.
The code is not runnable on the frontend. It needs to be transformed/built before that can happen.
Saying this doesn't have a build step is like saying a python script that compiles and runs a C program from source has no build step.
Yes, I'm aware the code doesn't run natively on the frontend. But we aren't talking about that.
That's exactly what everyone in this comment chain is talking about (even though you just updated your previous comment to make it sound different).
my apologies for using controversial wording. I'd love to confirm that we still must have some sort of transpilation / transformation because no Web Browser can consume JSX code directly (after all, JSX is just syntactic sugar, not a base language).
What I meant by "no build" is "no bundling". I elaborated more in this wiki: https://github.com/fullsoak/fullsoak/wiki/Concepts-&-Example...
Thank you for your help above in making things clearer <3
I would probably replace a lot of this language with something along the lines of "powered by Deno, enabling simplified, all-in-one tooling." You don't want it to look like you're taking credit for the features that Deno is responsible for. Would also help me understand what your project offers vs what Deno offers.
Hope that helps!
that's a nice perspective :) I totally had no intention for 'taking credits' as I assumed it's a 'given' that we run TS directly with Deno, Bun, or Node.js with the experimental flag.
I'll take this to my desk & update the wordings towards your suggestions above - thank you!
JIT?
> Then the app can be started up for local development: > > deno -A --watch src/main.ts
Sure looks like a build step to me?
Anyway I'm fine with one easy Deno build step, but Deno already has a fantastic web framework that supports SSR, so how is this different to Fresh?
Thanks for your thoughts! I do adore Fresh. In fact, I have run production projects on Next.js and Remix, and played around with Deno Fresh, and I enjoy them in different ways.
When I wrote "no build", I simply meant that we do not bundle the whole app into a single file.
Fresh is indeed very close to what I'm trying to explore here, yet if I understand correctly about Fresh, we still need a real build step: https://fresh.deno.dev/docs/concepts/server-configuration#-b...
Disclaimer: I have nothing against build steps, I just wish to explore an alternative approach where we completely do without them!
Thanks for the reply! I don't quite understand why you want to avoid a build step. Normally when people talk about that what they really mean is they don't want to have to run a build command, but you still have that.
To put it another way, what is the downside of Fresh's build step that you avoid?
Ah please don't get me wrong, there's no build command in my example. The command to start the app directly is: `deno src/main.ts`
and `main.ts` is an original source file, it's not a "bundle" of many files together, like in other setups with build config (tsconfig, webpack config, babel config, etc.)
I wouldn't call Fresh build step a downside either. With build step, there comes a build config (https://fresh.deno.dev/docs/concepts/server-configuration#-b...).
Imo, Fresh' build config is already way simpler than the "traditional" webpack approach (https://deno.com/blog/node-config-hell). Here in FullSoak, I only wish to push this boundary further ie. "no build config at all".
Sorry, slightly confused. From JSX docs:
> The difference is that the precompile transform analyses your JSX statically and stores precompiled HTML strings if possible. That way a lot of time creating JSX objects can be avoided.
So if there are compilation errors, who is stopping me from running without the build?
Hi! My apologies if the wording was confusing :( By "no build" I mostly meant "no bundling" (so: we're not combining all files into a single js bundle entry).
As for JSX itself: if we choose to use it, for sure we still need to transform it back to vanilla JS. I elaborate more in this wiki: https://github.com/fullsoak/fullsoak/wiki/Concepts-&-Example...
I've been wanting to make a no-build webapp using Mithril.js[1][2], with plain-JS type annotations that don't require build steps (TypeScript's JSDoc syntax [3], but I'm looking forward to the proposed type annotations[4]). With something like this, type-checking would still require running a command when using Node.js, but it's just an optional developer dependency since the code would still be just standard JavaScript.
But in the end I've not done that because I figured it's more effort than it's worth, compared to just doing server-side rendering with other backend languages and just using JS where needed (not necessarily "raw" JS, I just mean it as in "not having a full-page component").
I'm just letting you know that there are definitely some people like me that would like if more JS tooling didn't require a build step or specific runtimes (like Deno or Bun) as a hard dependency.
[1]: https://github.com/MithrilJS/mithril-node-render
[2]: https://github.com/StephanHoyer/mithril-isomorphic-example/
[3]: https://www.typescriptlang.org/docs/handbook/jsdoc-supported...
[4]: https://github.com/tc39/proposal-type-annotations
kudos to the MithrilJS project & also for having earned visibility on OpenCollective <3 I can see the (much respected) history track of this project.
Having "survived" the "Internet Explorer ages" of the www, I can share that my heart always has a slot for "vanilla JS" (& anything towards its direction). When coding solo and/or for light-weight (enough) projects, I also tended to do pure JS.
This looks great. I would love to see something like this evolve to become the industry standard.
My only worry between then and now is will it run into a wall if it is unable to solve problems that build steps did?
Does it handle extensions that webpack did browser shims? I assume those will just be imported modules.
And of course it is a new-thing-to-learn(tm) which is always a tough sell to getting it used in a corporate setting. For good reason.
Here's some things I like about the idea, mostly duplicating what you said already:
1. By holding your project to a no-build constraint, that means we won't go down the rabbit hole of toolchains like we did with bower, webpack, etc. to fix any problem. Ever. Yay!
2. You really did simplify the "build" step. My personal experience has been that that has always been a source of frustration, especially since most developers just want to get-shit-done and the more deep-diving devs would have to martyr themselves to get it working again. Now hopefully they just need to understand one set of config to tweak to get the application working as is.
3. It feels to me like your project will own any breaking issues that come out of it. It's always been a pain when there was complexities at the edges of parts of the toolchain. If NPM v16 breaks with webpack v5 or whatever its version scheme is, one or the other needed to upgrade to fix it and the ownership of the issue wasn't always clear. Sometimes it would take awhile because of a niche interaction between the two. And of course upgrading past it had other painful breaking changes your legacy app needed to address.
Anyways, looks good! Keep it up & good luck! I'm curious to see where this goes.
my appreciations!
You're absolutely correct at the "problems that build steps do". One example is the whole loader stuff (e.g. SCSS, Less, and the plethora of other things we can "just import (tm)" into our TSX components). For now it was a conscious decision that I keep things "stupid simple" as I shared in a Bsky post: https://bsky.app/profile/mrkha.ng/post/3lg3qw377ss27
Re. the "selling" part, it's also my wish to see how people resonate with this. Maybe not the framework itself, but only the concept of using standard specs (ie importmap + TypeScript runtime) - & since it's just bare standards, let's see if it attracts frictions (or not).
I keep a #buildinpublic blog for FullSoak on my bsky page: https://bsky.app/profile/mrkha.ng
Not sure if it's better than a Discord or sth like Tulips chat, but imho it doesn't matter, as long as there's a safe "draft space" to jot down the thinking-out-loud process, all while getting potentially feedback & help from everyone.
My next immediate exploration goals: make this framework compatible with deployment solutions such as Cloudflare Workers and Smallweb.run - atm I can't guarantee 100% success rate, but excited to see how it turns out.
Can I ask (partly for my benefit, partly for yours) for a short summary of what the problem is I might have, that this tool solves?
i wouldn't really introduce this as "a problem solver" :) It's more like an exploration of an alternative approach that combines base concepts such as:
- import map: https://preactjs.com/guide/v10/no-build-workflows/#import-ma... - TypeScript runtime: https://www.reddit.com/r/typescript/comments/y8tsav/comment/... - SSR & Hydration: https://zustand.docs.pmnd.rs/guides/ssr-and-hydration
But if I have to pick my brain and find a benefit that this approach brings, i guess it would be that we now avoid the entire "config hell" and cognitive load of managing build setups. This article shares some of this view: https://deno.com/blog/node-config-hell
Disclaimer: i have nothing against standard build processes that we've used for years. I've juggled a lot with browserify, webpack, and their successors & siblings. I just feel it's worthy to give a spotlight for an approach where we completely go without them :)
I like it! I spun up a little remixable Glitch project based on your demo so that I could play with it in a web editor. Thanks for sharing. https://glitch.com/~fullsoak
Wonderful!!! I wanted to provide a Live Demo, I tried with Deno Deploy, but I got a brick wall there because of some unintended blocker (ironically haha): https://github.com/denoland/deploy_feedback/issues/802
My next best choice was to extend the support to Bun, and then deploy it with Render.com: https://fullsoak.onrender.com/
I wasn't aware Glitch can also support Deno. So, sincere appreciations for your Glitch example <3 <3
Neat! I'm working on a self-hostable platform to host my deno apps (https://smallweb.run), I wonder if I would be able to your framework on there.
Hi! Kudos for the work on SmallWeb. I actually attempted to run this on your platform as well. I was able to run it partially on Cloudflare workers, so I trust it's compatible with environments like SmallWeb as well. Let's see!
Does this support serverless environments like cloudflare workers and val town[0]?
[0] https://www.val.town/
Hi, I just wish to update that: since fullsoak@v0.9.0, support for Cloudflare Workers has been added in experimental mode :)
Enabling this on Cloudflare Workers has been a rather challenging journey, due to the fact that the file-system APIs (that FullSoak uses) are not available on Cloudflare Workers. In fact there are still some bugs to squash, but I'm excited to share an early PoC: https://github.com/fullsoak/cloudflare-workers-examples
Live Demo here: https://fullsoak-cloudflare-workers-examples.dklab.workers.d...
Nice! I'll check out this demo in the morning
I managed (with some struggles) to get it deployed with Cloudflare Workers here: https://fullsoak-cloudflare-example.dklab.workers.dev/
But it's a long way until it's groomed & released as a standard feature. I'll share more details in the near future!
I'll also check val.town later. On a related note: someone was suggesting https://www.smallweb.run/ as well.
It would be cool if it's supported everywhere :)
Taking twobof my favorite parts of the ecosystem (ts and jsx) and leaving behind the rest (webpack). Good luck!
You are aware the term full soak is slang for sex right? Intentional name?
no I had completely no idea. Is this a generation gap thing, or maybe I just lived under a rock for too long - thank you for the heads up haha. If this causes too much friction, for sure it should be renamed..
The slang term "soaking" is primarily used in the Mormon community for a particular method of theologically-acceptable premarital intercourse.
morman teenagers do 'soaking' because they were told active participation in pre-marital sex like thrusting is taboo while soaking inside… resisting the urge to thrust… satisfies the condition
the lore continues that third persons jump on a bed they're all on is a surrogate for thrusting
not generational, just mormon things
maybe do something like fullsock instead? idk just a thought
i like that sound of that. Possibility for a nice logo image too!
Very cool will try it out. Like the bun support
thank you! You may find a Live Demo example (deployed as a Bun app) mentioned in this wiki: https://github.com/fullsoak/fullsoak/wiki/Concepts-&-Example...
And Jude was kind enough to roll out a Deno example on Glitch: https://glitch.com/~fullsoak
Isn't this what VanJS is?
wow I wasn't aware of VanJS before. It looks nice!
in my limited exploring of VanJS so far, I like that it also takes the direction to simplify things. That said, afaik VanJS simplifies the "JSX" part (so: we don't have to transpile from JSX to vanilla JS because... we don't even use JSX :D).
For the target output (which we need to start the actual app), afais, VanJS still involves this build step: https://github.com/vanjs-org/vanjs-org.github.io/blob/master...
( we can see it being used from `package.json` at the "build" step: https://github.com/vanjs-org/vanjs-org.github.io/blob/master... )
VanJS can be used just fine without a build step, and I do so.
The first instructions in https://vanjs.org/start are for this.
ahh good to know :) Thanks - I'll try it out for sure.
Also irrelevant but VanJS does have a way more invested logo & better name than "FullSoak" which I cooked up at 4am xD
SSR - server side rendering
Can I just add to the other "words have meaning" comments?
> FullSoak is (mostly) WYSIWYG. Compared to sophisticated frameworks such as Next.js or Remix, FullSoak is actually very "stupid looking": 1) you start with a "Controller" file (as in good old "MVC") which 2) renders your TSX component as text/html content (i.e. a plain string), and then 3) the content hydrates itself on the client side.
Unless it integrates a gui page editor, it's not wysiwyg.
And hydration on the client side is very much not SSR.
Also "stupid looking" doesn't really mean "simple".
There may be something interesting here, but the naming / description is really all over the place and misleading.
Additionally, "no build" when writing typescript and jsx/tsx is not possible. The web does not have native support for these files, so by definition there must be a build step.
I think the tech here looks good, but the terminology needs a big overhaul.
thank you! You are both right that the wording could use some revamp. Perks of hacking on sth til 3am and writing a dirty README that leaves a stigma for years haha.
Also by "no build" I mostly meant "no bundling". If you look at the source code of the example deployment: https://fullsoak.onrender.com/app - you'd see that every HTML file loads a single .js file. Sometimes we can "lazy load" the entire component .tsx file (if we choose to do so).
So there's no bundling of the whole app into 1 single "entry point". From JSX/TSX to vanilla JS, we do need a "transpilation" step, and right now it's done ad-hoc (on every request). Some caching technique could be employed to make this scale & perform, but it's a topic for another day I guess.
Definitely need to find a coherent wording to describe this whole concept without causing mix up or misunderstanding. Thanks again for pointing these out!
Should point out that "no bundling" has serious trade-offs. From https://vite.dev/guide/why.html#why-bundle-for-production
> Why Bundle for Production
> Even though native ESM is now widely supported, shipping unbundled ESM in production is still inefficient (even with HTTP/2) due to the additional network round trips caused by nested imports. To get the optimal loading performance in production, it is still better to bundle your code with tree-shaking, lazy-loading and common chunk splitting (for better caching).
Completely agreed! And "trade-offs" is the perfect keyword here. In exchange for zero cognitive load (ie. complexities in managing build config & consistency between dev & prod setups), we get a bunch of ESM, rendering the performance of our app dependent on browser loading optimizations (among other things).
I'll try to benchmark this "no build" setup on mdeium-large codebases, also comparing between different use cases (e.g. blog-like website vs rich-interactive web app such as "online photo editing") and let's discover the pros and cons of everything :)
[dead]
Also wondering what is meant by fullstack.
I was expecting Laravel/Ruby on rails
it's a valid question. In the JavaScript / TypeScript community, we usually understand "fullstack" as "isomorphic": https://www.lullabot.com/articles/what-is-an-isomorphic-appl...
Laravel and RoR are veteran giants in the Web Framework industry. I'm sure they cover "isomorphy" in their own ways, just that at the time they were born, the terms "isomorphic" and "fullstack" weren't even coiled.
This "FullSoak" framework is by no means aimed to be as full-fledged as the likes of Laravel / RoR / or even other JavaScript frameworks such as Next.js, Remix, SvelteKit, etc. - but it stays true to the "isomorphy" concept, where the same code is runnable on the browser & the server alike.
[flagged]
[flagged]
I like the no-build approach, but I'm afraid the problem is bigger.
For years, a new framework has appeared every week (it feels like every day) that promises to solve all problems with the latest buzzwords. The mere fact that this happens shows that today's web development suffers from a plethora of unsolved fundamental problems.
Instead of fighting a problem with workarounds (and thus new problems), it would be nice if the community would sit down and ask itself how we can create a future that makes frameworks obsolete.
Sometimes I get the impression that we have more of a social problem than a technical one. If browser vendors, developers, managers, corporations, startups, freelancers and everyone else involved sat down at a table and talked constructively with each other, things would certainly be possible that would save everyone a lot of work, or am I wrong?
It's also a thorny political problem.
Remember that Dart started as an attempt to evolve web programming past some of the perceived deficiencies of JavaScript. It came out of Google, who also maintains a significant share of the web platform via Chrome. There were a bunch of snarky comments about Google trying to colonize the web and force its new language upon everyone. Fast forward a decade+: now most professional web dev is done in TypeScript, a Microsoft language that's backwards compatible with JavaScript. JavaScript itself has evolved to address some of the complaints of the past. Dart is now the VM embedded in Flutter runtime, and has sworn off ever being baked into a browser.
There are two methods that have been successful at changing the web:
- Spend countless manhours and calendar years building consensus among dozens of people through the standardization process, and hope at the end of the day that your pet proposal is one of the few that survive. There are many awesome proposals that have never made it out of committee.
or
- Build a thing that's compatible with the existing platform (e.g. React, CoffeeScript, etc.), and get a critical mass to adopt it organically, until is has the influence that the web platform will change to meet the demand.
> it would be nice if the community would sit down and ask itself how we can create a future that makes frameworks obsolete.
The community is not an entity, it can't sit down and ask itself things, new ideas appear and the good ones get adopted. You can't prevent the existence of alternative approaches and ideas.
thank you for your approval of the 'no build' approach. We don't have to necessarily discuss the "framework perspective" of this topic - this all is more like a concept, a "lego mashup" of several standards:
- import map: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/sc... - TypeScript runtime: https://www.reddit.com/r/typescript/comments/y8tsav/comment/... - SSR & Hydration: https://zustand.docs.pmnd.rs/guides/ssr-and-hydration
So even without naming a new framework, one can simply pick up the "base concepts" above and mix them together, and have something similar :)
(of course as @root_axis mentioned: sooner or later any concept materializes as a "framework" or at least a "library" - so while we unfortunately can't change the nature of society, we can actively choose what we use & what we don't use. Psss: tbh i'm not really a framework person myself haha)