Show HN: A no-build fullstack SSR TypeScript web framework
I'd love to seek your insights on a fullstack web framework that employs a different approach: no build.
It's not a new concept. The folks as Preact mentioned it: https://preactjs.com/guide/v10/no-build-workflows/
However, in the Web Framework market, I've yet to find many that support both "no build" and "SSR". There's always some sorts of "client mount" and "server mount" and either has (or both have) to go through a build (bundling) process.
With the build process, there comes additional maintenance efforts and cognitive load. I've enjoyed wrestling with tsconfig, webpack config, all sorts of presets and plugins countless times... When things work, they just work, but when we need sth a bit custom or unconventional, then we're almost always in for a tough ride. (or it's just me )
Not to say I'm against any existing build workflow. In fact I benefited a lot in the past from webpack, and i'm very positive about modern bundlers like Parcel 2, Turbopack, rspack, etc.
I just feel it'd be fair to save some slots for the "no build" route :)
To this end, I spent the last month working on a prototype of a TypeScript fullstack SSR web framework. It's compatible with Deno and Bun runtimes. I'd love to make it compatible with Node.js as well (at some point).
The framework registry page (https://jsr.io/@fullsoak/fullsoak) summarizes the motives expressed so far.
An example deployment is available at: https://fullsoak.onrender.com/app
The code behind the deployment above: https://github.com/fullsoak/bun-examples
PS: you may see Preact being used & mentioned everywhere but I'm positive that React is 100% supported as well (just drop-in & use). I just happened to choose Preact to experience it more for myself.
I look forward to your thoughts :) and learning if this might (or might not) be a feasible idea at scale. And perhaps, which future directions you would see this (or something like it) goes. Thank you much for any insight!
[+] [-] bsimpson|1 year ago|reply
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)?
[+] [-] thesephi|1 year ago|reply
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...
[+] [-] root_axis|1 year ago|reply
[+] [-] IshKebab|1 year ago|reply
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?
[+] [-] thesephi|1 year ago|reply
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!
[+] [-] the_arun|1 year ago|reply
> 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?
[+] [-] thesephi|1 year ago|reply
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...
[+] [-] quectophoton|1 year ago|reply
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
[+] [-] thesephi|1 year ago|reply
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.
[+] [-] skipants|1 year ago|reply
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.
[+] [-] thesephi|1 year ago|reply
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).
[+] [-] jbreckmckye|1 year ago|reply
[+] [-] thesephi|1 year ago|reply
- 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 :)
[+] [-] thesephi|1 year ago|reply
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.
[+] [-] blinkymach12|1 year ago|reply
[+] [-] thesephi|1 year ago|reply
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
[+] [-] pomdtr|1 year ago|reply
[+] [-] thesephi|1 year ago|reply
[+] [-] nbbaier|1 year ago|reply
[0] https://www.val.town/
[+] [-] thesephi|1 year ago|reply
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...
[+] [-] thesephi|1 year ago|reply
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 :)
[+] [-] darepublic|1 year ago|reply
[+] [-] digitaltrees|1 year ago|reply
[+] [-] thesephi|1 year ago|reply
[+] [-] lerp-io|1 year ago|reply
[+] [-] SignalM|1 year ago|reply
[+] [-] thesephi|1 year ago|reply
And Jude was kind enough to roll out a Deno example on Glitch: https://glitch.com/~fullsoak
[+] [-] cmrdporcupine|1 year ago|reply
[+] [-] thesephi|1 year ago|reply
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... )
[+] [-] cma|1 year ago|reply
[+] [-] viraptor|1 year ago|reply
> 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.
[+] [-] nosefurhairdo|1 year ago|reply
I think the tech here looks good, but the terminology needs a big overhaul.
[+] [-] demarq|1 year ago|reply
I was expecting Laravel/Ruby on rails
[+] [-] unknown|1 year ago|reply
[deleted]
[+] [-] alecnotthompson|1 year ago|reply
[deleted]
[+] [-] lerchmo|1 year ago|reply
[deleted]
[+] [-] unknown|1 year ago|reply
[deleted]
[+] [-] slowtec|1 year ago|reply
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?
[+] [-] bsimpson|1 year ago|reply
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.
[+] [-] root_axis|1 year ago|reply
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.
[+] [-] thesephi|1 year ago|reply
- 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)