Don't use one. There's nothing React / whatever really gets you anymore that you can't get from native Web Components and all the effect and suspense garbage it comes with serves literally no point anymore. It's time has officially come and gone.
As far as Typescript goes, if there's no one else contributing to your project and you don't like it - don't use it. It is useful to bind contracts into things you provide, but contracts are for two or more people.
For good builds, etc I'd recommend using Bun if you just want a standard kit you don't want to think about too much or Vite.
There's nothing React / whatever really gets you anymore that you can't get from native Web Components and all the effect and suspense garbage it comes with serves literally no point anymore. It's time has officially come and gone.
I strongly disagree with this statement.
To be clear, I think not using a framework at all can be a fine option, and I also think React has a lot of issues that make it a poor framework. My own personal preference would be for SolidJS, that's what I usually go for if I'm using a framework, otherwise I'll sort of hand-roll things if they aren't too complicated. Either way, I am not trying to denigrate web components or claim that React is some brilliant tool that solves all your problems. However:
Web components are not a replacement for React. Web components are mostly orthogonal to React, they should be used for different things.
React provides, roughly, three major things: reactive state (i.e. when I change some application state, trigger the appropriate side effects including updating the UI); templating (i.e. a declarative syntax for describing how the UI should look depending on the state); and state management (i.e. how do I stay in control of a complex state tree). It isn't necessarily great at all three (templating is great, reactive state is overly complicated by the UI = f(state) paradigm, and state management exists but is mostly supplemented by third-party libraries), but all three are present.
Web components provide two things: a set of APIs for isolating parts of the DOM in different way, and a declarative syntax for executing these APIs from HTML. It's also worth keeping in mind that the APIs aren't necessarily even tied to web components - you can use the shadow DOM without ever creating a custom component - but the two parts are mostly connected for historical reasons.
Many people use web components via Lit, but Lit is a fairly standard web framework, much like React, that just happens to use web components internally. When you use Lit, you get all the reactive state, templating, state management goodies that you get from React and other frameworks, but only because Lit is providing them, and not because they have anything to do with web components themselves.
You should reach for web components if:
You are writing code that will be embedded into a variety of different contexts and frameworks, and you want consumers to be able to use a consistent syntax to pass data into your code
You are writing a widget that is entirely self-contained with very clearly defined inputs and outputs, essentially something like a date picker or a chart widget that can be dropped into any page.
That's probably not the case in this instance, in which case web components aren't really adding much.
I also don't agree with your comment about the "effect and suspense garbage". In fairness, React makes effects more complicated than they need to be, but both tools are incredibly useful. Effects are how you interact with things outside of the React world, and suspense is how you cope with asynchronous data. If you don't have these things, you need to either load all data upfront (impractical for anything that's actually reactive where that data can change) or you manually manage that asynchronicity everywhere that it's needed, essentially building your own less-good version of suspense. All frameworks have something like suspense, although different frameworks have different APIs and names for it. Svelte and SolidJS in particular are actively exploring this space in detail because of how useful it turns out suspense can be.
Maybe it’s because it’s what I’m familiar with, but to me, Web Components seem really complicated with their slots and shadow dom, etc, while JSX seems more like simple HTML templates, directly in JavaScript. If React seems too complicated, there are simpler ways to get JSX syntax.
I would rather pass parameters to templates as JavaScript values than mess with html attributes.
I agree that web components are a good choice. If nothing else it will help you organize a library and think about reusability of widgets. Then if you decide to use react or angular or anything else you can make wrappers for the web components and continue to use them. Also you can share them with the community if you want.
Contracts are helpful for one person as well. They are used to define and inforce certain types of invariants. Without a build step you can even do this across the front-end/back-end. My preferred setup these days is a JSDoc annotated tree of .mjs files on the front-end and TypeScript on the back-end, both in the same repo.
Disclaimer: not a frontend developer, take this with a grain of salt.
I’ve had brief experiences with Svelte (not SvelteKit - that’s the server one) and I have to say it was pleasant enough for a person like me, with strong BE background and definitely not a JS enjoyer.
It checks a lot of your boxes: strong compiler, hot reloads, good ecosystem.
I don’t really understand what you mean by “close to bare metal as possible”, cause to me that means C lol.
By the way, I’ll use the occasion to say that I’m a big fan of delphitools! Thanks for working on it.
Ah, that was my bad - I mean, little abstractions. I write JavaScript or HTML, the next time I reload that should be what's loaded, and not go through endless levels of minification, obfuscation and caching, at least for development environments. Bad wording on my part, and glad you're enjoying DT!
I hear good things about Svelte, it's currently in the running along with Ember and my personal front runner Vue, but I've had personal bad experiences with a messy Svelte codebase before, so I guess we'll see?
Svelte projects can be messy because it's fairly lean and doesn't impose a structure, so it's up to you to keep your project organized. Sveltekit is much more opinionated, and can also be used to make SPAs (without a backend). If you want something "close to the metal" as js can be, Svelte is a good choice. I haven't worked with Ember for more than 10 years, but I recall it was also a rather rigid framework, though I liked it.
Personal preference: Svelte for something really small, Vue for a bigger SPA, Sveltekit if I need a backend.
I'll also add that I've been writing JS (and using frameworks) for at least 15 years, and all frameworks are converging towards the patterns initially used by Vue.
I haven't had a chance to use it in a project, because I work for a company that's been doing a lot of React lately (and I want nothing to do with front end stuff, anyway) but...HTMX. It's an anti-JavaScript framework that focuses on giving you things that might actually need to be dynamic in a markup-driven interface and otherwise avoids JavaScript. You just write and return HTML.
Not OP, but I think I can answer this a little bit. You can do everything in vanilla HTML/CSS/JS, but if you need to make a lot of UI and want to be able to reuse it you will end up writing some sort of framework yourself either.
For some use cases that works perfectly cromulent, in other cases it becomes complex to maintain fast. Ready made frameworks do help there and can be a valid choice.
React is overused for sure and as it is the only tool many devs know they tend to try and nail everything down with it. But, there are plenty of other valid choices who, for certain use cases, make parts of web development a bunch easier than it would be without them.
The way I see it, the main selling points of frameworks are standardization and compatibility. They make it easier to hire a [framework] developer to replace the previous one and they come with varying levels of built in patterns that help stop interchangeable developers from making messes. Once upon a time they also helped solve cross browser compatibility, but these days, for most use cases, that isn't near as much of an issue as it once was. The last selling point is also outdated: adding functionality that's hard to implement in, for example, vanilla css/js. It's been a long time since I've encountered something that's significantly easier to do with a framework than it is with modern css/js. YMMV of course.
It's true that you'll end up writing something like a framework if you build a vanilla UI, but whether or not that takes more time depends on various factors. It definitely doesn't have to. And unless you really mess things up, your bespoke UI is going to be lighter weight than the framework alternative.
I'm not sure I see the maintainability angle. Are you thinking because many people aren't familiar enough with vanilla and so have a hard time understanding or writing it in a logical way? It certainly doesn't demand any bad patterns by nature.
Something I think it's easy to forget is that html/css/js essentially is a framework. One that's been iterated for the use case (websites/apps) for 30 years.
Not that frameworks aren't useful in lots of cases but, as nothing more than language constructs, they don't add as much as I think people sometimes assume.
Also: coding agents. The time to do X in a framework has now become basically identical to the time to do X without the framework. The remaining difference is load time on a slow connection and resource usage on a cheap device. In that context frameworks are just adding weight. Provided of course that the coding agent is in the hands of someone who is fluent in the underlying languages. Otherwise it could potentially be better to use a framework you're more familiar with, or with more good idioms than bad in the training data.
Anyway, I appreciate the digression, but my curiousity was more specific to @delphi's situation. It seems like an ideal opportunity to hand roll the UI instead of spending that time learning a new framework. Especially when a frontier model is almost guaranteed to give you a solid answer to every version of "how do I do this thing in vanilla js" you're likely to encounter.
Yeah, that's what it's gonna come down to, realistically. I'm between Vue, Svelte and Ember right now, with Ember coming from a personal recommendation of a close personal senior designer friend. Going through the tutorial right now and I quite like it so far.
I've really enjoyed Vue, and long been interested in Svelte. Note though that both include a build step. You mentioned wanting to avoid complexity where possible, so that's worth bearing in mind. Something like Alpine.js would be the more minimal solution, if you just wanted to include a .js file and be on with it.
Vue can technically be used as a library loaded at runtime as well. However, SFCs are so much nicer to write components in that I think it's well worth the build step. Plus you get all the other natural goodies like easily being able to add dev dependencies like linters, etc.
Mithril is a very close to metal, but still powerful framework. It's so close to metal that the only things you need to write an application is the bundle and regular JS. Or you could use JSX with the help of Webpack.
I like to use it for small projects . IMO it only a more robust router that can handle nested components.
However, your third point suggest you really don't want something like this.
Edit: The way to get the best practices suggestions is with a linter like ESLint, but that involves messing more with the tooling.
Typescript is pretty the de-facto default in JavaScript world these days. Out of curiosity, is it Typescript or the fact that strongly typed languages are something you aren't too familiar with? There is some valid reasons to stick to stronger typing, but Typescript also often gets made overly complex by some folks.
I'm not married to JavaScript as the runtime.
If it needs to run in the browser JavaScript or a superset are basically your options. Technically speaking you could do stuff with WebAssembly but I am not sure what the benefit would be for the tools available on the UI side. I mention UI specifically since you seem to be looking for a framework to do the front-end, which WebAssembly is bad at. But, for a lot of the image manipulation, encoding, hashing, etc it could be a valid choice. Just seems out of scope for what you are asking.
I'm looking for fast build times, a smart-ish compiler that can ideally hot reload and give me insights into bad practices (Next.JS does this quite well)
How about basically no build times? If it is mostly the UI you are concerned with you could explore Web Components . You write them in vanilla JS and HTML without the need to build them. Web Components are not without their issues though, dealing with shadow DOM styling can be a pain for example. And you still would need to build all reactivity yourself.
As far as bad practices goes, I would throw a linter against it (eslint) and for good measure also prettier so you have consistent markup as well.
If you want something like hot reloading you can include something like browser-sync or I guess vite.
As close to bare metal as possible, I can't begin to enumerate the amount of times the NextJS Turbopack auto-caching thing has caused me significant headaches.
Web components is the closest you will get while still have somewhat of a "framework". The alternative is doing much of it basically just in vanilla HTML, JavaScript and CSS. Which is possible, though does require more planning and thought in some areas. Something you might not want to deal with but it would check a lot of boxes you mentioned.
As far as other actual frameworks go, Svelte is often fairly popular with the crowd who don't like a lot of the React paradigms. No JSX, components that are basically HTML and as far as I know no useEffect as a crutch react does. No practical experience here myself, but it is what I encounter most.
Having said all that, completely switching everything around can be quite the undertaking. Not just doing the work of converting all tools but also learning all new paradigms and ways of working. Next.js in itself might be you biggest headache and is for many people. I'd first look at switching to just React if I am being honest, simplify the tech stack you have now and then reorient.
I don't mind a strongly typed language, but you know, I'm not building missiles here. I don't need my compiler to yell at me because i forgot a "type: whatever" in a context where only one type would ever be passed anyways. It just kind of cramps my style. I'm familiar with strongly typed languages. Hell, I started with C# back in the late 2000s. It just feels shoddy in TS, but I'm also not an engineer, so this might be a personal hangup.
I think that might be a matter of tweaking your linter or TypeScript settings to turn off warnings you don't care about? It's the sort of thing I'd ask a coding agent how to tweak.
Regarding not letting the agent do too much, I put something like this in my AGENTS.md:
If the user asks a question in a prompt, answer the question and do not edit any files, to give the user a chance to adjust their request.
Then I can ask all the questions I want without the agent being too much of an eager beaver, but I can also tell it to fix something specific.
I don't need my compiler to yell at me because i forgot a "type: whatever" in a context where only one type would ever be passed anyways.
....and give me insights into bad practices
Okay so, speaking from experience, I will fight tooth and nail to only use strongly typed languages moving forward, and I say that as someone who held similar opinions.
The main reason i'm going to double down on this for you especially is because you're supporting a tool that you intend for use by others. Maybe you're very good at ensuring things don't change, but chasing down a 'oops this typo meant this function threw out a string instead of an int which caused a bug 29 functions later' is something I will heavily desire to never do again.
It's why I proselytize F# because it both has strong typing, but type inference where I don't have to bother to declare so long as the compiler can figure it out. It'll yell at me the moment it's unsure of a type (Hey asshole this could be int or string, tell me so i can tell what else you've done wrong), but doesn't waste my time with me declaring every single one.
THAT SAID, I recognize that code that's written is often more important than code that could be. If you just can't gel with it, don't, and use whatever you like.
I do strongly recommend keeping in the back of your mind if you do find yourself chasing down runtime bugs, that tools like typescript help you eliminate the majority of that problem. It all comes down to "i'd rather the compiler yell at me than spend an hour chasing runtime bugs", but oddly I get it from the other angle where "well typescript is better but its still not good enough, so why bother".
Fair enough. Well, the rest of my advice still applies. Basically what others also said, if you really want a framework Svelte is good choice. Web Components bring down the amount of building even further and doing it all vanilla is technically also possible.
Typescript is pretty the de-facto default in JavaScript world these days.
I've yet to work at a company that uses it. I've had exactly two coworkers that loved it. Both didn't last long because they tried shoehorning it in and no one else liked working with it. It's awful for readability.
Lately I’ve been using Hono libraries a fair bit for web stuff. They are pretty lightweight and they are portable across JavaScript environments, so if you want to build a web app using Deno or Cloudflare Workers instead of Node.js, you can. (I use them with Deno.)
Hono itself is just a router: given an http request to a URL that matches a pattern, call the function you choose. I also like Hono JSX for generating html using functions in a .tsx file instead of insecurely concatenating html strings like a caveman. It takes the place of HTML templates and works both on the server and in a browser.
Other libraries I inevitably end up using are Valibot for validating any JSON coming in from the outside (either config files or web requests) and Dax for running OS commands, so I can write all my scripts in TypeScript instead of bash and have them be fairly readable.
For bundling client-side JavaScript, I was running the esbuild command directly from a build script, but now I invoke it using an npm package. This lets me write client-side code in TypeScript. I also use htmx to swap in parts of html pages and keep client-side JavaScript to a minimum.
If you want native, there are now a few native directly GPU rendered Webassembly solutions you can use. Most native languages have one, I have hear most about Rust based ones, like egui. I have no personal experience with them but it is an option. Probably overkill and slower to load then a webframework, but hey, why not.
This isn't a complete answer to everything, just another data point to add alongside the other discussions here.
I also just don't get on with React's endless use effect garbage
I was going to come in here to also suggest Svelte, but you'll almost certainly need some level of $effect given what some of the tools doing. Svelte's runes are a similar enough model, so if you're not enjoying (as stated elsewhere in this thread) that way of thinking then drop it.
Otherwise, if you think you can get away with plain HTML and JS then why not try that for a couple of the tools and see how you go? I see some people have also suggested Web Components; they aren't my favourite so I personally would be starting without them and then add them in later on for things that need a more component-y model.
and have little love for TypeScript
I will admit it took me a lot of time and pain to understand how the Typescript compiler wanted to be fought against. It's now ingrained in my head, to the point that I now find its type system to be incredibly expressive. It was a long journey.
If you find yourself still wanting a semi-typed experience with plain JS, most editors allow you to run the Typescript language server over JS files, and will pick up JSDoc comments like /** @type {number} */ as a way of selectively adding types to otherwise untyped code.
I'm looking for fast build times, a smart-ish compiler that can ideally hot reload and give me insights into bad practices
Vite is the compiler behind pretty much everything except Next.js at this point (well, and anything still using webpack). It'll give you your hot reload. It will, however, still minify and bundle everything, which I saw you comment on in other comments.
As for insights into bad practices, this is usually covered off by a combination of compiler plugins (if you're using a framework) or ESLint plugins. I suppose it depends on what you mean by "bad practices" and what you want them to prevent you from doing.
bkimmel | 16 days ago
Don't use one. There's nothing React / whatever really gets you anymore that you can't get from native Web Components and all the effect and suspense garbage it comes with serves literally no point anymore. It's time has officially come and gone.
As far as Typescript goes, if there's no one else contributing to your project and you don't like it - don't use it. It is useful to bind contracts into things you provide, but contracts are for two or more people.
For good builds, etc I'd recommend using Bun if you just want a standard kit you don't want to think about too much or Vite.
Johz | 16 days ago
I strongly disagree with this statement.
To be clear, I think not using a framework at all can be a fine option, and I also think React has a lot of issues that make it a poor framework. My own personal preference would be for SolidJS, that's what I usually go for if I'm using a framework, otherwise I'll sort of hand-roll things if they aren't too complicated. Either way, I am not trying to denigrate web components or claim that React is some brilliant tool that solves all your problems. However:
Web components are not a replacement for React. Web components are mostly orthogonal to React, they should be used for different things.
React provides, roughly, three major things: reactive state (i.e. when I change some application state, trigger the appropriate side effects including updating the UI); templating (i.e. a declarative syntax for describing how the UI should look depending on the state); and state management (i.e. how do I stay in control of a complex state tree). It isn't necessarily great at all three (templating is great, reactive state is overly complicated by the
UI = f(state)paradigm, and state management exists but is mostly supplemented by third-party libraries), but all three are present.Web components provide two things: a set of APIs for isolating parts of the DOM in different way, and a declarative syntax for executing these APIs from HTML. It's also worth keeping in mind that the APIs aren't necessarily even tied to web components - you can use the shadow DOM without ever creating a custom component - but the two parts are mostly connected for historical reasons.
Many people use web components via Lit, but Lit is a fairly standard web framework, much like React, that just happens to use web components internally. When you use Lit, you get all the reactive state, templating, state management goodies that you get from React and other frameworks, but only because Lit is providing them, and not because they have anything to do with web components themselves.
You should reach for web components if:
That's probably not the case in this instance, in which case web components aren't really adding much.
I also don't agree with your comment about the "effect and suspense garbage". In fairness, React makes effects more complicated than they need to be, but both tools are incredibly useful. Effects are how you interact with things outside of the React world, and suspense is how you cope with asynchronous data. If you don't have these things, you need to either load all data upfront (impractical for anything that's actually reactive where that data can change) or you manually manage that asynchronicity everywhere that it's needed, essentially building your own less-good version of suspense. All frameworks have something like suspense, although different frameworks have different APIs and names for it. Svelte and SolidJS in particular are actively exploring this space in detail because of how useful it turns out suspense can be.
skybrian | 16 days ago
Maybe it’s because it’s what I’m familiar with, but to me, Web Components seem really complicated with their slots and shadow dom, etc, while JSX seems more like simple HTML templates, directly in JavaScript. If React seems too complicated, there are simpler ways to get JSX syntax.
I would rather pass parameters to templates as JavaScript values than mess with html attributes.
hobbes64 | 16 days ago
I agree that web components are a good choice. If nothing else it will help you organize a library and think about reusability of widgets. Then if you decide to use react or angular or anything else you can make wrappers for the web components and continue to use them. Also you can share them with the community if you want.
tanglisha | 16 days ago
This is my first time really looking at Web components. It looks like react used to look.
pete_the_paper_boat | 16 days ago
Thanks for providing a link, I legit had no idea there's an actual API called Web Components.
teaearlgraycold | 16 days ago
Contracts are helpful for one person as well. They are used to define and inforce certain types of invariants. Without a build step you can even do this across the front-end/back-end. My preferred setup these days is a JSDoc annotated tree of
.mjsfiles on the front-end and TypeScript on the back-end, both in the same repo.teaearlgraycold | 16 days ago
You've lost me
nullbuilt | 16 days ago
Disclaimer: not a frontend developer, take this with a grain of salt.
I’ve had brief experiences with Svelte (not SvelteKit - that’s the server one) and I have to say it was pleasant enough for a person like me, with strong BE background and definitely not a JS enjoyer.
It checks a lot of your boxes: strong compiler, hot reloads, good ecosystem.
I don’t really understand what you mean by “close to bare metal as possible”, cause to me that means C lol.
By the way, I’ll use the occasion to say that I’m a big fan of delphitools! Thanks for working on it.
[OP] delphi | 16 days ago
Ah, that was my bad - I mean, little abstractions. I write JavaScript or HTML, the next time I reload that should be what's loaded, and not go through endless levels of minification, obfuscation and caching, at least for development environments. Bad wording on my part, and glad you're enjoying DT!
I hear good things about Svelte, it's currently in the running along with Ember and my personal front runner Vue, but I've had personal bad experiences with a messy Svelte codebase before, so I guess we'll see?
0xSim | 15 days ago
Svelte projects can be messy because it's fairly lean and doesn't impose a structure, so it's up to you to keep your project organized. Sveltekit is much more opinionated, and can also be used to make SPAs (without a backend). If you want something "close to the metal" as js can be, Svelte is a good choice. I haven't worked with Ember for more than 10 years, but I recall it was also a rather rigid framework, though I liked it.
Personal preference: Svelte for something really small, Vue for a bigger SPA, Sveltekit if I need a backend.
I'll also add that I've been writing JS (and using frameworks) for at least 15 years, and all frameworks are converging towards the patterns initially used by Vue.
redwall_hp | 16 days ago
I haven't had a chance to use it in a project, because I work for a company that's been doing a lot of React lately (and I want nothing to do with front end stuff, anyway) but...HTMX. It's an anti-JavaScript framework that focuses on giving you things that might actually need to be dynamic in a markup-driven interface and otherwise avoids JavaScript. You just write and return HTML.
Wes | 16 days ago
I feel that htmx makes more sense for web apps that closely integrate server elements. It sounds like that isn't the case with this project:
Note that Tildes itself uses Intercooler, the predecessor to htmx.
post_below | 16 days ago
Why do you need a framework? HTML/CSS/JS can do all the things, but it sounds like you probably know that, so I'm just curious.
creesch | 16 days ago
Not OP, but I think I can answer this a little bit. You can do everything in vanilla HTML/CSS/JS, but if you need to make a lot of UI and want to be able to reuse it you will end up writing some sort of framework yourself either.
For some use cases that works perfectly cromulent, in other cases it becomes complex to maintain fast. Ready made frameworks do help there and can be a valid choice.
React is overused for sure and as it is the only tool many devs know they tend to try and nail everything down with it. But, there are plenty of other valid choices who, for certain use cases, make parts of web development a bunch easier than it would be without them.
post_below | 16 days ago
The way I see it, the main selling points of frameworks are standardization and compatibility. They make it easier to hire a [framework] developer to replace the previous one and they come with varying levels of built in patterns that help stop interchangeable developers from making messes. Once upon a time they also helped solve cross browser compatibility, but these days, for most use cases, that isn't near as much of an issue as it once was. The last selling point is also outdated: adding functionality that's hard to implement in, for example, vanilla css/js. It's been a long time since I've encountered something that's significantly easier to do with a framework than it is with modern css/js. YMMV of course.
It's true that you'll end up writing something like a framework if you build a vanilla UI, but whether or not that takes more time depends on various factors. It definitely doesn't have to. And unless you really mess things up, your bespoke UI is going to be lighter weight than the framework alternative.
I'm not sure I see the maintainability angle. Are you thinking because many people aren't familiar enough with vanilla and so have a hard time understanding or writing it in a logical way? It certainly doesn't demand any bad patterns by nature.
Something I think it's easy to forget is that html/css/js essentially is a framework. One that's been iterated for the use case (websites/apps) for 30 years.
Not that frameworks aren't useful in lots of cases but, as nothing more than language constructs, they don't add as much as I think people sometimes assume.
Also: coding agents. The time to do X in a framework has now become basically identical to the time to do X without the framework. The remaining difference is load time on a slow connection and resource usage on a cheap device. In that context frameworks are just adding weight. Provided of course that the coding agent is in the hands of someone who is fluent in the underlying languages. Otherwise it could potentially be better to use a framework you're more familiar with, or with more good idioms than bad in the training data.
Anyway, I appreciate the digression, but my curiousity was more specific to @delphi's situation. It seems like an ideal opportunity to hand roll the UI instead of spending that time learning a new framework. Especially when a frontier model is almost guaranteed to give you a solid answer to every version of "how do I do this thing in vanilla js" you're likely to encounter.
Moogles | 16 days ago
Vue or Svelte. I just do design now but I found Vue and Svelte to be easier to pick up then React or Angular.
[OP] delphi | 16 days ago
Yeah, that's what it's gonna come down to, realistically. I'm between Vue, Svelte and Ember right now, with Ember coming from a personal recommendation of a close personal senior designer friend. Going through the tutorial right now and I quite like it so far.
Wes | 16 days ago
I've really enjoyed Vue, and long been interested in Svelte. Note though that both include a build step. You mentioned wanting to avoid complexity where possible, so that's worth bearing in mind. Something like Alpine.js would be the more minimal solution, if you just wanted to include a .js file and be on with it.
Vue can technically be used as a library loaded at runtime as well. However, SFCs are so much nicer to write components in that I think it's well worth the build step. Plus you get all the other natural goodies like easily being able to add dev dependencies like linters, etc.
Kremor | 16 days ago
Mithril is a very close to metal, but still powerful framework. It's so close to metal that the only things you need to write an application is the bundle and regular JS. Or you could use JSX with the help of Webpack.
I like to use it for small projects . IMO it only a more robust router that can handle nested components.
However, your third point suggest you really don't want something like this.
Edit: The way to get the best practices suggestions is with a linter like ESLint, but that involves messing more with the tooling.
creesch | 16 days ago
Typescript is pretty the de-facto default in JavaScript world these days. Out of curiosity, is it Typescript or the fact that strongly typed languages are something you aren't too familiar with? There is some valid reasons to stick to stronger typing, but Typescript also often gets made overly complex by some folks.
If it needs to run in the browser JavaScript or a superset are basically your options. Technically speaking you could do stuff with WebAssembly but I am not sure what the benefit would be for the tools available on the UI side. I mention UI specifically since you seem to be looking for a framework to do the front-end, which WebAssembly is bad at. But, for a lot of the image manipulation, encoding, hashing, etc it could be a valid choice. Just seems out of scope for what you are asking.
How about basically no build times? If it is mostly the UI you are concerned with you could explore Web Components . You write them in vanilla JS and HTML without the need to build them. Web Components are not without their issues though, dealing with shadow DOM styling can be a pain for example. And you still would need to build all reactivity yourself.
As far as bad practices goes, I would throw a linter against it (eslint) and for good measure also prettier so you have consistent markup as well.
If you want something like hot reloading you can include something like browser-sync or I guess vite.
Web components is the closest you will get while still have somewhat of a "framework". The alternative is doing much of it basically just in vanilla HTML, JavaScript and CSS. Which is possible, though does require more planning and thought in some areas. Something you might not want to deal with but it would check a lot of boxes you mentioned.
As far as other actual frameworks go, Svelte is often fairly popular with the crowd who don't like a lot of the React paradigms. No JSX, components that are basically HTML and as far as I know no
useEffectas a crutch react does. No practical experience here myself, but it is what I encounter most.Having said all that, completely switching everything around can be quite the undertaking. Not just doing the work of converting all tools but also learning all new paradigms and ways of working. Next.js in itself might be you biggest headache and is for many people. I'd first look at switching to just React if I am being honest, simplify the tech stack you have now and then reorient.
[OP] delphi | 16 days ago
I don't mind a strongly typed language, but you know, I'm not building missiles here. I don't need my compiler to yell at me because i forgot a "type: whatever" in a context where only one type would ever be passed anyways. It just kind of cramps my style. I'm familiar with strongly typed languages. Hell, I started with C# back in the late 2000s. It just feels shoddy in TS, but I'm also not an engineer, so this might be a personal hangup.
skybrian | 16 days ago
I think that might be a matter of tweaking your linter or TypeScript settings to turn off warnings you don't care about? It's the sort of thing I'd ask a coding agent how to tweak.
Regarding not letting the agent do too much, I put something like this in my AGENTS.md:
Then I can ask all the questions I want without the agent being too much of an eager beaver, but I can also tell it to fix something specific.
Eji1700 | 16 days ago
Okay so, speaking from experience, I will fight tooth and nail to only use strongly typed languages moving forward, and I say that as someone who held similar opinions.
The main reason i'm going to double down on this for you especially is because you're supporting a tool that you intend for use by others. Maybe you're very good at ensuring things don't change, but chasing down a 'oops this typo meant this function threw out a string instead of an int which caused a bug 29 functions later' is something I will heavily desire to never do again.
It's why I proselytize F# because it both has strong typing, but type inference where I don't have to bother to declare so long as the compiler can figure it out. It'll yell at me the moment it's unsure of a type (Hey asshole this could be int or string, tell me so i can tell what else you've done wrong), but doesn't waste my time with me declaring every single one.
THAT SAID, I recognize that code that's written is often more important than code that could be. If you just can't gel with it, don't, and use whatever you like.
I do strongly recommend keeping in the back of your mind if you do find yourself chasing down runtime bugs, that tools like typescript help you eliminate the majority of that problem. It all comes down to "i'd rather the compiler yell at me than spend an hour chasing runtime bugs", but oddly I get it from the other angle where "well typescript is better but its still not good enough, so why bother".
creesch | 16 days ago
Fair enough. Well, the rest of my advice still applies. Basically what others also said, if you really want a framework Svelte is good choice. Web Components bring down the amount of building even further and doing it all vanilla is technically also possible.
moonwalker | 16 days ago
I've yet to work at a company that uses it. I've had exactly two coworkers that loved it. Both didn't last long because they tried shoehorning it in and no one else liked working with it. It's awful for readability.
skybrian | 16 days ago
Lately I’ve been using Hono libraries a fair bit for web stuff. They are pretty lightweight and they are portable across JavaScript environments, so if you want to build a web app using Deno or Cloudflare Workers instead of Node.js, you can. (I use them with Deno.)
Hono itself is just a router: given an http request to a URL that matches a pattern, call the function you choose. I also like Hono JSX for generating html using functions in a .tsx file instead of insecurely concatenating html strings like a caveman. It takes the place of HTML templates and works both on the server and in a browser.
Other libraries I inevitably end up using are Valibot for validating any JSON coming in from the outside (either config files or web requests) and Dax for running OS commands, so I can write all my scripts in TypeScript instead of bash and have them be fairly readable.
For bundling client-side JavaScript, I was running the esbuild command directly from a build script, but now I invoke it using an npm package. This lets me write client-side code in TypeScript. I also use htmx to swap in parts of html pages and keep client-side JavaScript to a minimum.
adutchman | 16 days ago
If you want native, there are now a few native directly GPU rendered Webassembly solutions you can use. Most native languages have one, I have hear most about Rust based ones, like egui. I have no personal experience with them but it is an option. Probably overkill and slower to load then a webframework, but hey, why not.
secret_online | 16 days ago
This isn't a complete answer to everything, just another data point to add alongside the other discussions here.
I was going to come in here to also suggest Svelte, but you'll almost certainly need some level of
$effectgiven what some of the tools doing. Svelte's runes are a similar enough model, so if you're not enjoying (as stated elsewhere in this thread) that way of thinking then drop it.Otherwise, if you think you can get away with plain HTML and JS then why not try that for a couple of the tools and see how you go? I see some people have also suggested Web Components; they aren't my favourite so I personally would be starting without them and then add them in later on for things that need a more component-y model.
I will admit it took me a lot of time and pain to understand how the Typescript compiler wanted to be fought against. It's now ingrained in my head, to the point that I now find its type system to be incredibly expressive. It was a long journey.
If you find yourself still wanting a semi-typed experience with plain JS, most editors allow you to run the Typescript language server over JS files, and will pick up JSDoc comments like
/** @type {number} */as a way of selectively adding types to otherwise untyped code.Vite is the compiler behind pretty much everything except Next.js at this point (well, and anything still using webpack). It'll give you your hot reload. It will, however, still minify and bundle everything, which I saw you comment on in other comments.
As for insights into bad practices, this is usually covered off by a combination of compiler plugins (if you're using a framework) or ESLint plugins. I suppose it depends on what you mean by "bad practices" and what you want them to prevent you from doing.