Hacker News new | past | comments | ask | show | jobs | submit login
Show HN: Skruv – No-dependency, no-build, small JavaScript framework (skruv.io)
123 points by SahAssar 6 days ago | hide | past | favorite | 163 comments

First: I find the diff to the previous step in the tutorial really nice, it helps to grok what changed nicely for me, well, similar to patch series do. Never saw that used in a general framework tutorial, or at least I do not remember doing so.

The framework itself looks OK from a quick glance, I'll see if I can give it a try sometime.

I'm searching a small and modern framework since a bit, for hacking together quick small prototypes, personal status-page frontends, and the like. I do not like using bigger frameworks there as after digging around in huge frameworks in the past for work, I want it really just end-to-end understandable.

I actually thought about hacking the few helpers together myself, but I rather like to reuse something to avoid combating different browsers (even that landscape isn't as colourful as it was), and the like. Also, I wanted also to avoid inventing "yet another minimal JS framework".

So, FWICT, Skruv seems to fit my bill actually quite nicely.

Two questions, just out of interest:

Any plans about how to develop and/or maintain this in the future?

Is this anyhow involved in a commercial operation, i.e., where you or other devs can get paid to invest some (maintenance) work into it?

> Any plans about how to develop and/or maintain this in the future?

Yes, I plan to continue developing and supporting it although I don't think I'll add too many features since I try to keep it focused.

> Is this anyhow involved in a commercial operation, i.e., where you or other devs can get paid to invest some (maintenance) work into it?

Yes, I use it professionally and can use some paid time to work on it. One of the reasons to post it here was to get some other devs eyes on it and to make it easier to bring on new hires by hopefully building a small community.

(Disclaimer: I'm author of mithril.js, another minimalist JS framework)

I'm curious why you decided to export multiple tag names as opposed to using hyperscript. Something that helped mithril.js gain more traction was that while it is idiomatically meant to be used as plain JS, it's also compatible with JSX tooling for the folks that want that. Also, some things are a bit awkward to express in terms of tag-names-as-functions (most notably, custom components require a hyphen in their names, and SVG tags need to be created with a different DOM API, and some have name collisions with HTML tags, e.g. `title`)

Skruv's html lib evolved from how I used hyperapp v0 and v1 a couple of years ago. It seems from what I can tell that hyperscript, hyperapps `h` function and skruv's `h` function follow similar ideas and signatures and I got my inspiration from hyperapp which I guess got at least some inspiration from mithril.

One thing I like about exporting multiple tag names is that it (to me at least) makes it more readable. When I switched over my last team from JSX to JS (that was in hyperapp v1) they did not like writing `h('div')` but were fine with `div()` so I put that together and over time it grew on me. I also kinda like being able to see what elements are used based on the import at the top of the file, but that's secondary.

Skruv still exposes a `h` function that is used for web-components, like `h('my-component')` and you can use it for all HTML elements or for JSX. The rest are just for readability and convinience (and are really just curried versions of `h`).

As for SVG I mostly do that by tracking if a parent was a SVG element and if so I assume all children are SVG namespaced (again, inspiration taken from hyperapp) until I hit a foreginObject element which means to switch out of the SVG namespace. If you have better ideas or feedback on that I'd be happy to listen.

Thank you for taking a look and I'd love to hear any other thoughts you have!

I believe jorgebucaran (hyperapp author) was aware of mithril.js' existence and may possibly have been inspired by it, but I don't take credit for hyperscript itself (it was already a concept used by various other systems - the word "hyperscript" itself comes from the name of a project[0], and there were already other similar frameworks like mercury[1] at the time).

For mithril.js specifically, the hyperscript variation offers an extra feature that AFAIK not many other libs do: the ability to write emmett-like CSS expressions as the tag name (e.g. `m('input.required[type=password]')`). Totally understandable if you think that's too much sugar for your lib, but I've found it handy for usage with CSS frameworks like bootstrap. Mithril.js users also appreciate it and some interesting unexpected patterns came out of that (e.g. `const Foo = '.some.tailwind.thing'; <Foo />`)

BTW, funny story: mithril.js partially took inspiration from an ancient library called dōmo[2] which - as it turns out - uses the tags-as-functions pattern.

[0] https://github.com/hyperhype/hyperscript

[1] https://github.com/Raynos/mercury

[2] https://jed.github.io/domo/

For those who have these requirements, you should try Mithril.js. It's small, robust, stable, has a strong community, and has been around since 2014. It's as close to plain JavaScript as you can get.

Mithril's flexibility is so well designed, we're still finding new and innovative ways to use it, even though the base library rarely changes. Having used React and other libraries for many years, Mithril is still the simplest and most pleasant library out there.

lichess uses it (mithril) for what is one of my absolute favourite examples of a truly well done web application - everything about lichess is just so well executed that if the author of a product like that chose mithril that's a strong indicator it's at least worth a good look.

Interesting project! I recently created something similar[1] because I wanted a simple, easy to use, bloat-free micro framework to create single page applications. I also wanted it to be somewhat "battery-included" and provide things like routing and state management out of the box.

I think skruv comes with even bigger batteries (SVG support, Shadow Dom integration and additional vdom related apis), and I am curious to see how they all play together. The one thing that does seem a bit weird is the html helper functions... like Mithril, I went straight for hyperscript: I think it is very underrated right now but it is actually a good way to write a dom tree -- and you also get JSX support (nearly) for free.

Anyhow, keep up the good work, I think the world needs more micro frameworks like these: powerful but simple enough to be understood and extended easily if needed.

[1]: https://h3.js.org

Thanks! I haven't built in a router yet, but I'll publish the one in the Tutorial as a separate package as soon as I feel it covers enough use-cases.

On hyperscript: I prefer to keep the tag name separated from selectors, to me stuff like element type and classes/id's belong in different places and with css scoping built in I think you won't need as many classes so hopefully it won't be a big issue. In general I want the vDOM/HTML stuff to be a pretty direct abstraction on the HTML/DOM in the browser.

On JSX: There is a generic `h` function builtin that can be used as a target for JSX. I'll put together an example of it in the coming days. I still want the recommended way to use the framework to be without build steps, parsing or dependencies though.

Why is this syntax so popular? I haven't used it but it smells so weird..

https://skruv.io/Tutorial/step3/ (Inside the renderNode)

Nontheless, I like this direction of a small framework keeping it simple, like Vue was initially.

What’s weird about it? It’s the most obvious declarative way to build a hierarchy of objects in vanilla JS. It’s easy to read and straightforward to understand; if you want abstractions around it is completely obvious how you would go about building those yourself.

recreating html node declaration in JS with janky and verbose syntax for attributes and child nodes is not an answer to a problem anyone has.

I guess I shouldn’t reply to flippant drive-by comments, but how the heck can that be considered verbose, and what’s your non-janky suggestion that doesn’t introduce some kind of extra tooling or parsing?

The linked code doesn't show the full value of this technique, since its straightforward HTML that's coming out.

Now what happens if you want a collection of list items generated by looping over an array?

Assign classes based on some logical conditional?

Conditional rendering?

These are problems everybody has and every template language tries to solve with their own custom syntax.

The point of this method is that rather than create some half-assed template language, you just write Javascript code that acts on and generates a data structure that can then be converted into HTML.

Web components and tagged strings are the most obvious way.

Tagged template literals can certainly be nice, but they basically require you to ship a parser to the browser, or introduce a complex build step, or give up the idea of doing vdom-like patched updates. (Not sure I see how web components fit into this discussion.)

Web components use shadow DOM for that, besides I rather let the browser engine do what it does best.

This comment just makes no sense in a discussion about syntax. You want to do something completely different, that’s fine, but it’s not an answer to “why this syntax”.

Sure it is, use web components syntax.

What can I say, økseskaft to you too.

De nada.

Because you can pretty easily add a layer on top to make it nicer (like JSX). And it has the benefit of working with e.g. Typescript and give you type safety out of the box, unlike Frameworks that have their own template systems.

Agree: Once one deliberately throws out support for all but JS-enabled browsers, HTML doesn't matter that much anymore and at that point tooling support like making it possible to work in TypeScript becomes a nice bonus.

(Note however that while enjoy projects like these and also don't vilify most people who wrote JS-dependent websites, not even in my thoughts, I might think of those who write html with optional js-features as nicer people, more thoughtful/considerate and less childish ;-)

Throwing out support for HTML-only browsers is not a prerequisite for authoring a reactive UI with JS. Using Next.js, react-static, or even plain ReactDOM’s renderToString() you can generate static HTML+CSS for your pages, which would then be hydrated and become interactive only in user agents with JS enabled. Authoring components with awareness of that, you can degrade gracefully while reaping the benefits of type checking, reusable components etc. at development stage.

No, but the moment you depend on Javascript being enabled in the client, why not get rid of as much of html as possible and use a sane language like TypeScript?

Yeah, upon rereading I see I wasn’t replying to what you meant.

Honest question, why jsx over html/js and why particularly Typescript?

I have not used Skruv, but from my experience with vanilla js (document.createElement('div')), hyperscript (h('div')), and jsx (<div/>), jsx is hoesntly much easier to write and to read.

Why not Typescript?

Using a typed languge is such a productivity boon.

This a is an answer thats made for those "why you should use Typescript in 2021" medium articles that pop up on my feed ad nauseum.

The word productive on its own is wholly meaningless without elaboration. What makes a typed language productive? Does the size of the project matter?, why is vanilla js not productive? Is it a lines of code metric? Is it a test suite efficiency metric? Is it a quality metric?

Providing a thorough answer to your question would require a lengthy article. It's a bit much of an ask to have someone do this for you on HN.

But very briefly I would say that these are the benefits as I see it:

* Access to improved tooling. E.g. refactoring by renaming things is much easier to do without breaking things. Also auto-complete when using third party libraries is a huge benefit.

* Some errors are automatically caught during build-time. E.g. checking the data used in a template lines up with what the component should be passing to that template. Without typescript one should probably verify this via unit tests. With TS these tests are superfluous.

* Improved documentation. It's a lot easier to understand what the shapes are of data is that is being passed around in the application. It also provides the opportunity to define these in central locations (e.g. in the form of interfaces) which can then have additional documentation added to them.

I think the benefits are not so much specific to TS as they are general benefits of using types and a typed ecosystem.

There are two major flavors of syntax when it comes to minimalist/no-build JS templating:

1) tree of function calls like this or hyperscript - this is popular because the language syntax enforces markup well-formedness (e.g. you can't express `<b><i>foo</b></s>`) and it's easy to implement minimalist engines on top of this API style. Hyperscript in particular is also compatible with JSX.

2) template strings - this is popular because you can actually write angled brackets without a build step, but it tends to come at a cost of less syntactical safety (e.g. `<b><i>foo</b></s>` may or may not explode early enough in the dev cycle) and some might argue the semantics of various syntactical permutations are less clear and/or more complex to implement (e.g. what are these supposed to do? `<${a}>`, `<a ${[b, c, d]} />`, `<a ${'b=c'} />`, `a<b, c>d`, etc)

For template strings you can have a compiler or IDE plugin check the templates. For lit-html we have lit-analyzer, ts-lit-plugin, and lit-plugin (VS code) that do both general HTML linting and lit-html specific type-checking and syntax highlighting.

Sure, when you have compilers and third-party static analysis tools, the palette of what is feasible broadens significantly. I was speaking strictly about no-build-step frameworks.

OP was trying to keep their framework small and avoid a build step, both of which (especially the latter) would preclude the use of a DSL like JSX. Are you suggesting another approach other than function composition?

I have no problem with it, except in this variant the empty braces everywhere are a bit annoying (and seem very likely unnecessary).

I believe this is the original syntax for describing a virtual DOM.

This looks nice, especially how it deals with async functions and scoped styling out of the box. It’s to be expected that a submission like this prompts people skeptical of yet another JS framework, but I feel like it’s been a few years since the JS-framework-of-the-week phenomenon peaked.

Reagent (& Rum) are still IMO the state of the art in frontend web development: https://reagent-project.github.io/

You have to buy into ClojureScript though. Nothing wrong with ClojureScript per se, but adding a build step back in (plus the occasional transpilation weirdness) is pretty far afield from a native no-build JS system.

I’m not trying to say that Skruv is state of the art either, maybe it is, I don’t know. But using ClojureScript definitely raises the bar for who has the ability to use Reagent and who is willing to.

Yes, exactly. I did SPAs with ClojureScript for a while, but lately I've switched to server-side rendering with Rum. This post popped out at me since I've been thinking about options for adding interactivity to the front end without adding a build step.

I prefer re-frame over rum, but Reagent is amazing. So little churn over the life of the library is a great accomplishment.

{}... {} everywhere

why wouldn't you switch the attributes to the second param and set default value {}? seems really redundant this way

All the HTML functions are variadic, so you can write

        h1({}, 'text'),
        article({}, 'text'),
        footer({}, 'text')
instead of

    section({}, [
        h1({}, 'text'),
        article({}, 'text'),
        footer({}, 'text')
It's a choice, but I think without it you would have a lot more array openings/closings, and they would be more spread out instead of the empty objects, which are kept in the same place.

Your answer makes a lot of sense. I think you've made the right compromise.

A framework to do... What? Is this another view layer?

"Framework" actually has a meaning beyond "JS library". I'd normally not make this complaint, but the entire home page only tells me what it isn't and some traits it doesn't have, aside from the hint it does weird things to CSS. (I tried to look at the tutorial, but it was a mess on my tablet.) It doesn't tell me why I might actually want to use it. After all, there's no library so concise that it wins the LOC comparison against not including it in a project.

Hah last year I did my case study of building an app with only web tech - no dependencies, build steps etc. - https://github.com/ivank/vanilla-teuxdeux

Figured out virtual dom is the one big missing piece to make webdev workable without any dependencies at all.

I can see other people are getting to similar conclusions:)

Everything that does not let me define the interface in HTML is a no-go for me.

HTML and CSS are a very good approach to define a GUI. And they will be around for a very long time.

This is the reason why I also don't use React, Flutter and all the other ways to build web/mobile/whatever applications.

I am torn on Vue. It is kind of ok because it lets you work with HTML templates with placeholders. Great. But it alters your data (puts getters/setters on everything) even when you don't need that.

The best solution in my book is to use a javascript template engine like handlebars.

Like the other commenter mentioned, you should look at Svelte. I had the same perspective as yours and I've worked on multiple modern JS frameworks and Svelte is the closest I can get to mapping my mental model of how a web page works (HTML, CSS, JS) with the framework.

Actually, I should correct myself - yes, the breakdown in terms of technology is HTML, CSS, JS but the underlying abstraction is actually - structure, presentation and functionality.

This is where, imho, Svelte really shines. It helps you to map your mental model of structure, presentation and functionality to it's corresponding implementation of HTML, CSS, JS with a sprinkle of syntactic sugar. This goes way far in keeping the code easy to understand and maintainable in my opinion.

Svelte does three things that I disagree with: uses unconventional JS-ish syntax (like '$:' labels and how it does import/export), requires a very framework-specific templating language and requires a large build step.

Since those are pretty central to how svelte is used and it's philosophy I don't think svelte is a good fit for me, personally.

We all value different things in different frameworks, and that's great!

I agree. I've learnt my lesson and I will _NOT_ be running "npm install" on any greenfield projects anymore. I like the idea of Svelte but I do not like its dependency on npm/node.

At least with Vue I can just include the library into the page, with no mandatory build step.

The trade-off is performance. If you don't build your application, you're offloading work to the client.

In the case of Svelte, you're also likely increasing the size of your site, since it transpiles down to simple JS instructions rather than abstracted framework calls.

Have y'all looked at RiotJS? My current favourite, not in my way, easy to reason about JS toolkit for building (all or part) of web-interface

As someone who helped lead the Polymer team in the transition from HTML-first Polymer to JavaScript-first lit-html/LitElement, I have some experience building both approaches.

I think that JavaScript-first is far better for templating the more general case (or the lower level foundation) because JavaScript is where your data lives. It's generally much easier to bring markup into JavaScript than it is data and data manipulation into HTML.

In HTML you need re-invent expressions, scopes, control-flow, references, and imports. You're going to spend more time and code implementing a less expressive, slower, and more proprietary system.

In JavaScript you just need a way to describe fragments of the resulting DOM (whether you prefer JSX, function calls, or tagged template literals), and the rest is just JavaScript.

Now, I do see benefit from the HTML-first approach for a lot of people and some use cases. One reason I also push on web components so hard is that with interop comes flexibility in allowing a mix-and-match of approaches. As a side-project I'm working on an HTML-first declarative component system layered on top of LitElement: https://github.com/justinfagnani/stampino-element

  <stampino-element name="simple-greeter" properties="name">
    <style type="adopted-css">
      :host {
        color: blue;
      <h1>Hello {{ name }}!</h1>

  <simple-greeter name="World"></simple-greeter>
This can interop with any other web component, so you can write your app components in HTML, but drop to JS for the most complex components and use JS-first third-party components and design systems.

There are - as with most things in life - pros and cons to each approach. With plain JS, it's absolutely true that you can let the language do its things when it comes to things like scope, control flow, etc as opposed to reinventing them. But at the same time, there are a million ways to loop in JS, and a more restricted DSL can offer very good optimization opportunities that cannot be reasonably implemented on top of a JS-based templating engine. You can also create custom syntax for cases where the language doesn't gel so well (e.g. each/else or await in svelte)

I've been slowly seeing more and more of a third approach where there's very little in the way of control flow in the template itself, where data is wired up using different constructs. Solid.js is an interesting example where it uses reactive constructs on top of "plain JS(X)", while encapsulating control flow inside components, which it is then able to optimize aggressively.

> optimization opportunities that cannot be reasonably implemented on top of a JS-based templating engine

You very much can do those optimizations in pure JS. lit-html's repeat() directive implements the list diffing approach used in ivi, Vue. It's invoked just like a higher-order function over an array and a mapper function: https://lit-html.polymer-project.org/guide/writing-templates...

I also don't think custom syntax is necessary or that useful. JavaScript has enough abstraction power in functions and objects that you can build very nice embedded DSLs without a compiler or custom template syntax.

but my main point is that both approaches are still valid, and rather than choose a framework based on its particular DX, we should move away from frameworks and be able to write individual components with whatever DX the developer wants, and have them all work together.

Yes, you can do some optimizations. Keyed list diffing is obviously doable (any respectable vdom does it). Marko-style optimizations (i.e. compiling to no JS hydration logic whatsoever) is far more difficult. IIRC Dominic from the React team looked into it at some point a few years ago but it truly is a very very difficult class of optimizations to implement generically while also supporting unrestricted JS syntax.

> Everything that does not let me define the interface in HTML is a no-go for me.

Interesting. I'd say that anything that doesn't let me check that the interface contract for a component is met, i.e. that the component is receiving all the data from the parent that it has declared as required, is close to a no-go for me. I want my tools to be able to statically analyse my code and tell me where I screwed up.

I know I'm old fashion, but I still don't like it when JavaScript and HTML is mixed. HTML comes first, then maybe some JavaScript to enhance features and finally CSS to make things look pretty. It's probably not a good way to built modern websites, but that's sort of the model I understand.

Also any mention of NPM makes me not want to use something. Frankly the tooling around JavaScript is horribly confusing, especially for someone who learned HTML 22 years ago.

> Frankly the tooling around JavaScript is horribly confusing, especially for someone who learned HTML 22 years ago.

Why wouldn't the said someone take a day or two to update themselves on javascript tooling in order to get less confused? There are so many great resources available.

The browser itself takes far longer than a day or two to learn to program even without tooling, considering that content is roughly the size of MDN; there is so much js tooling and documentation and of such wide variety that a year or two would not be enough for even a light review (roughly the content of github/js). And even that is not enough time to develop heuristics for deciding between approaches. And it doesn't begin to touch tooling, like editors, or deployment and runtime.

Here is a video of a lovely man who invented Erlang, Joe Armstrong, expressing confusion about how to build a "modern" javascript program: https://www.youtube.com/watch?v=lKXe3HUG2l4 (hilariously he was using grunt - a tool which is now entirely out of favor).

Come on, this isn't that hard if you have minimal, or even outdated, web dev knowledge. There is like 3 major frameworks (Angular, React, Vue). Spend a few hours to look how it is to work with each one, make your choice and follow a tutorial. Congrats, you've made your first Single-Page App.

Of course if you've never written a line of code in your life, or if you're angry at the thought of using a dependency manager, you're going to have a hard time. And not only with the web stack.

So I've looked into React and the problem I have with it is that it's lauded as "simple" because it's "just a view kit."

However, there are an infinite amount of questions one has to answer when starting a new project:

- I see that state management libraries are in a lot of tutorials and talked about online. Which one do I pick? Redux? MobX? Something smaller? Do I skip it entirely? What are the consequences of that?

- Okay, so how do I deliver "pages" in React? Do I pull in React Router as well? I saw an article on using Hooks to replace RR. Do I do that instead?

- How do I handle authentication? Do I use JWT? Which library? I saw some comments on Hacker News that says JWT is terrible. Do... do I pick something else? I kind of need auth so I cant's skip it. What if I need to do OAuth?

- Do I use TypeScript? What is the scope of work for implementing it into my build pipeline? Is it worth it?

- Build tools. Sure, WebPack is the most popular but a lot of tutorials are for outdated versions. A lot of the times I'm googling "how do I do X webpack" and just get different JSON blobs to plug in.

It's just... so much. I just don't care. I don't want to configure Gulp or WebPack or whatever. I don't want to extensively research every dependency I have to pull in to get a working app. There is Facebook's create-react-app and that's a good start. Vue and Angular don't suffer as much from this because they focus more on being complete packages.

Doesn't matter to me though. Phoenix LiveView provides enough interactivity for me.

All fair questions :-) But you don't sound like a frontend developer. Are you writing something with a UI so complex that you would need React, Vue or Angular to implement it?

In their defense it’s been a year and I’m still learning React. Please don’t act like it’s something you understand in a few hours because it’s not. You might be able to copy-paste the example code and get something that works and sorta seeing what happens but to really understand takes a lot of time.

Assuming that this vanilla js should be familiar for anyone who has only ever written js that interacts with the DOM api:

    document.body.innerHTML = `
        Hello world
the React equivalent is no more complex:

    const HelloWorld = () => (
        Hello world

    ReactDOM.render(<HelloWorld />, document.body);
Add to this a couple of high-level concepts, i.e. that a React component re-renders if its arguments (props) or its internal state change, and you are 70-80% there. Learn the useState and the useEffect hooks, and you are ready to be productive. If you aren't ready for build tools yet and just want to play with the library, take Preact, which has a syntax option that does not require a build step [0]

How many hours should this take?

[0] https://preactjs.com/guide/v10/getting-started

The problem is that React might not exist over a couple of years.

I program for decades. Most of my old stuff using frameworks - say for example, Angular or Jekyll - doesn't work anymore. If I update I end up in a dependency hell that's even worse. It's like XSLT in XML. It will pass. :-)

> The problem is that React might not exist over a couple of years.

I agree with you in principle, but I think I disagree in details. Programming using standard web apis certainly feels more future-proof, and all the power to those who have adopted web components. But React doesn't look like it's going away within the next decade. And even if Facebook somehow implodes, and no other company steps up to support the work of the React core team, React's api has been copied by Preact, which has Google's backing; and JSX has spread even wider. Importantly, React in itself is larger than DOM — it is a reconciler that can be used for canvas/webgl (react-three-fiber), for mobile applications (react-native) and windows applications (react-native-windows). So there is a good indication that React will be with us for a while.

But again, I completely agree that many projects that get started with React don't need to have been.

> I program for decades.

Two decades ago, Perl was a good choice :-) And look where it is now.

We are lucky with the rigorous backwards compatibility of HTML, CSS and javascript. But planning for decades may be a bit of an extreme. I wouldn't like to inherit a frontend project that was written two decades ago and hasn't changed since then.

And yet you completely just proved my point.

If you think one gets to know React or Angular because one can follow a "Getting Started" tutorial for a couple of hours and get it to show an example page then you're in Dunning Kruger territory.

I never said that a tutorial was enough to master a framework, please.

The comment I was replying to was saying:

> there is so much js tooling and documentation and of such wide variety that a year or two would not be enough for even a light review

There's no need to learn the entire ever-evolving JS ecosystem. You pick a sane starting point (a framework tutorial) to get you up and running in a few days, and from there you learn what you _need_.

The trouble for newcomers starts at _which_ framework to hang your hat on. Unless that decision has been made for you by your employer choosing between, Vue, React, Svelte, Alpine, Angular or some additional ankle biters is overwhelming. What's the selection criteria? What's the payoff vs complexity cost of each? What's the support level? Is it coming in vogue (Svelte) or out of fashion (Angular)? Does it mandate additional tools/transpilers/packagers etc and how many? How hard are they to learn? Do they play well with some other tooling that is being used (say Typescript)? Finally how does it all get packaged as an app/website to publish?

It's a complicated mess and even seasoned JS developers struggle to answer the above questions. Oftentimes the justification for choosing a framework is that they had read about it in a forum like HN and wanted to try it. Nothing wrong with that for someone who lives and breathes those things but most people want to just get a CRUD UI up, these things are a massive time sink for what they purport to offer.

If, like you say, these people aren't frontend specialists and don't pick frameworks on the basis of what appears on the front page of HN, why should they reach for a framework as their first port of call anyway? Many conversations on HN seem to turn into an argument between old-school developers, who declare that there's nothing better than good old jquery and Bootstrap, and more hip developers who immediately drag in React, Vue, or Svelte. The middle-ground option of starting with plain modern JS and plain modern CSS is offered relatively rarely. Which is strange — this should be the default for those who are disoriented by the plethora of options on the frontend.

Especially since you suggest that such developers just need to get a CRUD UI up and running. You don't need a js framework for that.

Because one tried and the ecosystems is such a mess that there's no real logical place to start.

If you are tainted by old knowledge, then there are things that you wouldn't even imagine is required. Why to I need NPM? JQuery and Prototype didn't need a package manager. You have a ton of tools, different tools for different frameworks even.

The more I look into modern JavaScript the more confused I get.

> Why to I need NPM? JQuery and Prototype didn't need a package manager.

But that is a question that can be asked of any language. It's a given that any modern language would have a package manager. Ruby has gems, python has pip, rust has cargo, and so on. PHP didn't use to have a package manager, to the chagrin of many professional web developers, until finally there was Composer, and the php community breathed a collective sigh of relief. Package management is good. It helps you define all your project dependencies in a sane way in a configuration file, and put that in source control, rather than download all the dependencies locally and store those in source control.

Javascript had different package managers. It had bower. It had meteor packages. It had something else as well. It had different module formats. It has a rather convoluted history. Luckily, with the popularity of node, we now have only a couple — npm and yarn. Or just one, which is npm, if you consider only the standard tools that come bundled with node.

My last job did not use maven. We checked in the required jars into the repo and everyone cloned their copies from there. Builds took seconds and were always predictable.

My current job uses maven and I'd swear a good 20-30% of developers time is spent wrestling with maven dependencies. Especially on a new project.

If what you're primarily building is a web page with light interactivity, there's nothing wrong with jQuery (or a more declarative modern alternative like Alpine.js). React et al are intended for applications with enough complexity that trying to manage it procedurally becomes miserable and unmaintainable.

There's a lot wrong with how npm is used (primarily the never-ending recursive dependencies making proper auditing of the code you use all but impossible), but including tons of script tags on every page and hoping you got the right plugin order without introducing any conflicts was hardly the pinnacle of development.

There are two problems with modern JS, imo. First is all the people insisting you need to use some grotesquely complex setup running on Kubernetes to host a blog that gets a hundred page views per month. The second is that most frontend frameworks want to take over your entire app, and in some cases really want your backend to be running node too. It's usually possible to start small and enhance as you go, but it's not easy.

> there's no real logical place to start

One way — if you are at all interested that is — is to look for someone who can guide you through the current tooling landscape. For example, I believe Cory House's course on Pluralsight on choosing appropriate tools for a frontend project [0] should be informative in this regard. There are also free tutorials about this subject — for example on egghead.io [1]

The other way is to find the documentation on any of the popular tools: webpack, rollup, snowpack, vite, esbuild, etc. — and just follow along trying to set up a toy project and, by doing so, figuring out what the purpose of the tool is. See the recent Google's site on the comparison of modern tools [2] to find out what each of the tools is supposed to do for you:

[0] https://www.pluralsight.com/courses/javascript-development-e...

[1] this one might be useful: https://egghead.io/courses/how-to-use-npm-scripts-as-your-bu...

[2] https://bundlers.tooling.report

> I know I'm old fashion, but I still don't like it when JavaScript and HTML is mixed

Why not? I don't like it when UI logic is needlessly split up and seperated. I like it when things of the same concern are in the same place.

> Frankly the tooling around JavaScript is horribly confusing

I wonder what you think of the tooling and ecosystem for other languages is like? Python, Go, Swift, Rust, C#, Kotlin, C++, etc.

I learned HTML in 1995, and I don't have these problems.

Same here - today it's all React/Typescript with build steps for me. However I still get Ctrl/Cmd-S / see it right away of course.

> HTML and CSS are a very good approach to define a GUI.


because the currently existing HTML/CSS UIs with which I have the "pleasure" to interact do a very good job of convincing of me of the exact opposite

HTML is a text markup language and hence not very well suited to build a logical structure for the same reason that xml is not very well suited to describe data. And that is not because it cannot do it, but because it is too powerful.

What is better in my opinion is a mix. Use one language or specification to model your architecture and structure and then, strictly on top of that, write (x)html to define your content. (you could also use markdown, just choose a markup language)

Then, for the layout/design, use CSS that is completely separate from your site's structure and content; read: separate file, not embedded in the rest. Well, maybe CSS is insufficient and you also need to use Javascript or some language on top of it because the CSS is still lacking of lot of important things, but that's not a principal problem but a specific problem of CSS as a language.

With HTML you define a tree of elements. And you assign IDs and classes to those elements.

How is that not well suited to build a logical structure?

Because HTML (excluding web components which require JavaScript) doesn't have any way to handle repetition and conditionals.

Of ccourse the commenter does mention using a templating language but a lot of people will be annoyed with this basic language and just want the full lower of JS to generate the site structure.

doesn't have any way to handle religion

    <a religion="christian" href="...

Fixed to repetition.

Because it is too powerful. You can do something like this:

    <div class="main"> oh <div class="sub"> hello </div> </div>
This is valid HMTL but it is not a valid structure in any context that I could imagine, because what is the "oh" supposed to do there?

To prevent these (and other) mistakes, the way you can build up the structure should be restricted in a meaningful way and certainly not allow text and random positions and similar things. You could then describe this with a subset of HTML, but there isn't really any reason to choose it, except for "I'm used to it". Better choose your native programming language. And if it is not better than a HTML subset, maybe consider choosing your language.

> Everything that does not let me define the interface in HTML is a no-go for me [...] This is the reason why I also don't use React.

could you elaborate on that? How would you like to define interfaces in a way different from React or... anything else?

What's your opinion on svelte?

One big selling point on vue is that you can just use a tag script and map a vue object on your regular HTML page.

Ne need for build steps. No need for html in the JS script.

It feels like JS from the 2000, simple and light, but with reactivity and speed.

Of course, once you need it, you can just use the awesome ViteJS to get your backend build with SFC files.

This makes vue scale up, but also scale down, which is equally important.

Svelte seems to be set on having a server side build process for the front end. That is an even bigger no-go for me.

The complexity of React and the OPs framework at least be contained in the frontend. With a server side build step, the complexity of the frontend spoils over to the backend.

If you are building a documentation website, sure. Go implement a video-streaming platform using HTML/CSS only, that would be a real treat! :)

I'd guess you would like alpine.js

The font-family list in the stylesheet is both too long and weirdly specific, yet incomplete. I don't have any of these very specific Windows, Apple, or Android fonts installed on my machine, so it picks the first one it can find which is "Noto Color Emoji" and uses that as the main font. The end result that all the space characters are about two miles wide, and the rest is rendered using the browser default "sans-serif".

You list 13 different sans-serif fonts, and two emoji fonts. The browser is perfectly capable of picking its own Emoji font for emoji characters so this is all completely unnecessary.

Please just use "font-family: sans-serif" if that's what you want, otherwise use web fonts. There's no need for this level of complicated font family micro-management, that doesn't even work.

I used the base stylesheet from https://github.com/kognise/water.css, but I'll prune down the list. Thanks for the feedback!

EDIT: The font list is now down to 'sans-serif', so the issue should be fixed!

Can we start getting frameworks in other languages that compile to WebAssembly instead. We already have enough JS frameworks

Rust compiles to WebAssembly and has a few web frameworks already. Many other languages also have web frameworks and compile to JS. Today it is possible to do web development and avoid JS entirely.

I have tried writing websites with rust instead of JavaScript. Unfortunately, the tooling is just not there. More specifically, I am talking about wasm-bindgen, which provides two-way bindings. The problem with it is that since all the declarations are generated with build.rs, there is no autocompletion. Since I am spoiled by modern tooling, no autocompletion to me means not feasible pass demo stage. (https://github.com/rust-lang/rls/issues/1489)

Aside from the lack of autocompletion, passing rust closures to js land (DOM) is extremely janky as well. However, that might be caused by my lack of experience with rust.

(If you are curious, this is what I made: https://github.com/SCLeoX/non-grid-path-finder)

Codebases compiled to WebAssembly still cannot access the DOM directly. So yes, for now you still need JavaScript.


Yes, but languages/frameworks can provide their own abstractions to access the DOM and web platform so that you can avoid writing any JavaScript yourself, for example `web_sys` in Rust.

At this stage, it's so easy to create a new "framework" that they shouldn't be called frameworks anymore. They're just a way to organize code.

I mean I've probably made one of these for each app I built. It takes a couple of days to write and then you can modify it to fit your very needs...

Isn't "a way to organise" (code) exactly what a framework is?

At this point what would be interesting would be some framework that doesn't use vdom. :)

Kinda sad how little diversity of foundational concepts of the framework there is these days.

ES modules, because we can. vdom, because that's what everybody is doing, and async/await everywhere. Kinda boring.

I like the minimalism of this one though.

This is what Svelte does today. I think Svelte is the innovative one in the current state of things. :)


I agree about svelte. It leverages the foundations of the web - html and css - and adds some amazing reactive sugar!

If you want a simple library that doesn't use vdom, have a look at RE:DOM https://redom.js.org/#introduction

There are plenty of frameworks which don't use vDOM. In fact, if someone is coding up something new today they're less likely to use vDOM.

Also, solid.js

Can't read tutorial on mobile

Yeah, I couldn't make the tutorial work well on mobile since it has to show quite a lot at the same time. Rather than forcing it into a mobile view I decided to keep it as is. I might revisit that in the future and do something similar to svelte's tabbed interface.

The website is completely blank white for my samsung s7 android edge browser (but works fine on android chrome). If this was written using your framework, there's probably a bug that's causing it not to render.

Do you perhaps know the version of the browser? Thank you for reporting anyways and I'll take a look!

I get this error on console (Firefox 83):

Uncaught TypeError: Error resolving module specifier “skruv/html.js”. Relative module specifiers must start with “./”, “../” or “/”. index.js:3:64

Yeah, that's expected. It comes from the shim I'm using to support import maps, it's explained why the error is "wanted" here: https://github.com/guybedford/es-module-shims#polyfill-mode

I could probably silence it, but since I have examples with that module in the tutorial it felt dishonest to do so.


More feedback from my Firefox (Chrome appears ok): spacing between words is really large. Ticking off font-family (or having it just sans-serif) in developer tools seems to fix it.

Yeah, I got some other feedback that the font declarations from the base stylesheet I pulled in was a bit much. I'll fix it, thanks for letting me know!

EDIT: The font list is now down to 'sans-serif', so the issue should be fixed!

Looks great now, thanks!

Why is vDom an advantage?

The top nav bar gets duplicated vertically many times for me. Seems to only happen when Dark Reader is enabled. Weird. I might be wrong, didn't examine what's happening.

Yep, seems like dark reader injects some elements that the site does not like. I'll look into it, thanks for reporting!

Fixed now!

You're framework doesn't render on an older chrome android browser.

Would be great if the docs was mobile friendly.

Love it, that is how I do Web development when I control the development stack.


What browser, version and OS? The server is setup with pretty strict TLS settings, but modern browsers should work.

The site is TLS 1.3 only.

Please make sure you understand the unintended consequences of doing that


(Can't edit the previous comment anymore) I switched to mozillas Intermediate preset, seems to work on TLS-v1.2 clients according to SSL-Labs. Thanks for the feedback!

Yeah, I intentionally used mozillas Modern preset from their SSL Configuration Generator. I'll look at scaling it back to their Intermediate preset.

Edge 89.0.774.54 64-bit on Windows 10.

Can't rule out group policy settings fudging something though. I'll try another machine.

(Can't edit the previous comment anymore) I switched to allowing TLS-v1.2, hopefully that fixes the issue for you. Let me know if it doesn't and I can take another look!

Works fine now, thanks!

Just tried it on Edge 85 & Edge 89 and "it works on my machine". Please let me know if you find what the issue is!

can anybody who uses it compare it with mithril.js ?

I've come to expect the "why another JS framework" paragraph on project websites. For me, more attention garbing and unusual would be omitting it.

YAJF - Yet Another JavaScript Framework

Doesn’t work for me on Firefox 68.7.0 esr.

The current Firefox ESR release is 78.9.0 unless I'm mistaken, it should work on that. Currently I only support recent/current versions of browsers.


going to make a hello world app using skruv so I start the timer on my skruv exp

> uses plain JS for building up the DOM tree (normal functions, no JSX or template tags)

        oncreate: (e) => {
            console.log(e, 'was just added to the DOM')
    }, 'Hello world!'),

heh. I find it mildly funny when people recreate JSX from from first principles

Can you please follow the site guidelines when posting to HN, and the Show HN guidelines when posting to Show HN threads? Your comment breaks both of them, and is an instance of the snarky, dismissive culture that we're trying to avoid here. I'm sure you didn't mean it that way, but these things get upvoted, and condition the entire thread and ultimately the ecosystem.



JSX basically compiles down to function calls, so this is more like taking the JSX out of the loop. In react the equivalent JSX would basically compile to

    React.createElement("body", {
        oncreate: (e) => {
            console.log(e, 'was just added to the DOM')
    }, 'Hello world!'),
which does not seem that different, right?

If you want to you can use JSX with skruv as long as you tell the JSX compiler to use `h` instead, in which case it will produce this:

    h("body", {
        oncreate: (e) => {
            console.log(e, 'was just added to the DOM')
    }, 'Hello world!'),
which works with skruv.

Yes this was kind of my observation.

I find it funny that JSX even exists when writing helpers to build html with functions is such a trivial exercise and easy to read, but nope, lets add in some wonky XML with weird corner cases.

> and easy to read

Very arguable. I'll take "wonky XML" over JS function calls any day for readability, and apparently most people would too given that they write JSX rather than use `React.createElement` and that all major frontend view libs (angular, react, vue, svelte, mithril...) offer XML-like templating and people overwhelmingly use it.

Googled: "no dependency" javascript framework 37k+ results. "no build" javascript framework 45k+ results.

At this point I'd be seriously impressed by someone saying "I didn't create a new JS framework, instead I contributed to an existing one".

"Please don't post shallow dismissals, especially of other people's work. A good critical comment teaches us something."


There are also additional guidelines for Show HN threads:

Be respectful. Anyone sharing work is making a contribution, however modest.

Ask questions out of curiosity. Don't cross-examine.

Instead of "you're doing it wrong", suggest alternatives. When someone is learning, help them learn more.

When something isn't good, you needn't pretend that it is, but don't be gratuitously negative.


Did you try looking past page three in the search results?

And did you verify that at least a few of those pages contained the search terms?

Because in my experience that is not given:

- Google used to brag about crazy number of results but if I tried to go to page 5 it would admit there weren't any. I guess it was a naive bloom filter or something out of my league that caused it - and those that knew didn't care because it looked good for 99,999% of the users.

- Google has happily ignored double quotes for well over a decade now. Lately I've had some success by using the plus operator immediately in front of the doublequotes. Side note: I feel hesitant to write that. An UX-er from Google might notice it and fix that bug to make it consistent (consistently useless, that would be) :-/

These days I use DDG as default though and after being fooled a lot of times and one too many I don't even bother to look behind page 2 on Google since years ago.

Yeah, I try to address this on the start page.

I did contribute a bit to hyperapp for a while and used it professionally. They took a different path with v2 though and forking v1 to add the features listed proved to have a similar diff to writing it from scratch.

Ah yes, the three levels of laziness:

- writing new frameworks

- contributing to existing frameworks

- commenting on HN deriding those writing new frameworks

I don't know what the keywords are to Google for the 3rd type, but I suspect the result count would be the highest of all.

Yeah, same here. This framework development frenzy seems to me like procrastination from doing actual work. 'Gee, I finally have time to do this web site I always wanted! Well, let's start with the OS my custom browser will run on!'.

Please note, that this is not a dig at this particular project. I'm sure it's nice and all but I'm never going to use it because 1) what's the chance this'll be around and maintained in 6 months time? 2) no community support, probably no way to ask questions or see other people's questions, 3) what's the chance that 1 & 2 will change in a couple of months? This line of reasoning can be applied to most of the new frameworks out there I think.

Its not exactly procrastination because while creating framework you are deep into topic and amassed knowledge helps you in general, no ? You can't understand anything until you build it.

Hey, I didn't say procrastination's not useful-ish. I once learned, among other things, the difference between sleet and hail but that critical knowledge was of no use to the client or the project I was supposed to be working on ;)

In general you shouldn't be creating a framework, you should be making an application.

In general, any non-trivial application uses micro-frameworks (that you write) and macro-frameworks (that you use or write).

Not every reusable piece of code is a framework.

It kinda is, if someone packages it up and calls it that

Just what we need, another JS framework.

Is this for real?

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact