Hacker News new | past | comments | ask | show | jobs | submit login
Show HN: I built a 4kb alternative to React, Vue, etc for building web UIs. (synergyjs.org)
343 points by defx 9 days ago | hide | past | favorite | 162 comments

Just wait. You are going to start adding modules and eventually you're going to have a whole ecosystem. Someone is going to complain about the bloat and then build the new simpler JS framework that's basically your version 1.0. I've seen this movie several times over the last 10 years.

I don't understand how this is the top comment. It's so generic and lacks any investigation or insight; I could copypaste this as a reply to any software project post on HN and it could vaguely apply in the same way (but not specifically apply).

Case in point with JS libs and the following line: "You are going to start adding modules and eventually you're going to have a whole ecosystem". This happens with individual JS-built products using libs, but definitely does not happen universally with most JS libraries. Take React, the first comparator referenced in the post title: its ecosystem is entirely 3rd-party addons and the core is focused and single-purpose to this day. They've added a lot of internal complexity to their vdom implementation which adds code bloat, but it isn't what this commenter is describing.

Vague comments like this never apply to all cases (often apply to no cases). It's a lazy comment that contributes nothing without being specific to this new library. You need to read the code and develop some genuine insight to have this type of commentary.

> I don't understand how this is the top comment. It's so generic and lacking of any investigation or insight; I could copypaste this as a reply to any software project post on HN and it could vaguely apply in the same way (but not specifically apply).

Yes. And that is _exactly_ the point. These anti-bloat libraries either die or become the enemy they set out to defeat. We've been to this rodeo before, yes?

Nothing wrong with that per se. But we gain nothing by pretending this cycle doesn't exist.

Perhaps a smarter approach would be: I've replicated 80% of X's features with 20% of the weight. Here's what's missing.

Then if Library X puts on weight, so can you, if you want. But feather weight in and of itself is not a benefit per se (especially when it's likely temporary). It's a feature. And too often we all gets sucked into the feature trap because we forget it's ultimately about benefits.

> These anti-bloat libraries

This probably isn't true, but more importantly this statement misses the point because you're bundling a bunch of stuff into the "anti-bloat libs" bucket with no consideration for the individual architectures of each.

To come back to the example above—React—the core react library is 3.2kb[0] gzipped. (and it hasn't died out). What I'm selectively omitting here is the architectural detail that React have separated their API implementation (core), their renderers (DOM, Server, Native) and their templating (JSX), all of which are loosely coupled optional components. That's a very effective approach to omitting bloat, and is a model that can be copied in an approximately compatible way (see e.g. the anti-bloat Preact and Inferno, further examples of anti-bloat approaches that have not "died out")

[0] https://unpkg.com/react@17.0.1/cjs/react.production.min.js

[1] https://preactjs.com/

[2] https://infernojs.org/

> die

This idea puzzles me. It's not like the code suddenly breaks or the world changes so much as to render it completely obsolete.

It's borderline madness to keep chasing new and shiny things and then complain that things keep changing.

Stability is a feature, not a bug.

Call it Grey-Beard Cynicism if you will.

To be Clear; The submitted ShowHN is a welcome effort and espouses (imo) fantastic ideals and objectives. I'm glad that people like the developer take/make the time to contribute to the greater good of the open source community.

It is also great/fantastic/good/{some other positive superlative} that people like the submitter keep on fighting the good fight when it comes to program bloat.

While I'm not trying to read another persons thoughts here - Perhaps their comment was indeed meant as a 'oh another thing that's gonna end up bloated due to feature request creep' (which was my initial jaded reaction too although I just didn't think it was an opinion worthwhile posting as a comment that contributed something worthwhile to the conversation so didn't do so).

Call it a measure of the current global mood within the HN that the comment became the top voted comment.

As to what my point was? Uhmmm I forget.

Thanks for the kind words. I completely understand the cynicism, especially when it comes to the front end / javascript scene. I'm not entirely sure if the title I chose has helped or hindered more, but it has fuelled some discussion at least and I've got some good feedback and even a first contribution, so it's definitely been worthwhile.

History rhymes. Noting a pattern is insightful.

Only if there is one. Which it takes at least a modicum of time spent on analysis to ascertain.

It's a fun thing to do that lets you learn the core issues frameworks try to solve. People then post their work because we have to legitimately market ourselves and our work somehow.

There's lots of avenues that can be taken with things similar to react - and trying and experimenting can create some better methods. It's not as if react or vue were built in isolation from all the previous software.

> because we have to legitimately market ourselves and our work somehow.

Do we ?

You don't. But I did and now get paid 3 times more than I did before. There aren't enough high paying bay area jobs to go around for all developers in the world, so as they say, early bird gets the worm.

If we went to be "better than average" then yes. You must do something to stick out in order to get better jobs, more money, more fame, more power, etc.

> People then post their work because we have to legitimately market ourselves and our work somehow.

Wouldn't it be better if we experimented with radical new ideas for development instead of reinventing the same JavaScript wheel for 300th time?

We are though. One of the current shift that is happening is that frameworks are moving away from using Webpack and so on during development. Vue now has Vite, Svelte is moving to Snowpack, etc. This can speed up development iteration time by orders of magnitudes.

I agree that that would be swell but sometimes you have to practice the same movements as those that came before to learn something new?

Svelte did this by throwing away virtual DOMs and using a compiler to directly bind elements to data.

I've seen that too, but there are also tons of projects that stay true to their original intentions and it wouldn't make sense (to me at least) to morph synergy into a "one size fits all" framework. It has a clear set of responsibilities and my ultimate hope for this library is that it will be eventually become redundant as all of the features it provides become a part of the web platform itself.

Counterpoint: mithril.js has been feature complete for years, and the culture around it is to resist change for the sake of change (e.g. it didn't jump into the react hooks bandwagon like vue did, even though it's arguably more similar to react than vue is)

Ecosystem-wise, it encourages integrating with high quality vanilla libraries directly instead of having a react-this or vue-that for everything under the sun.

This approach has worked well, IMHO.

Three cheers for mithril.js! I've used it for a number of things, including a complete rewrite of a heavy old app that used Ext.js. It was very simple to set up dynamic page assembly for very fast and flexible UIs.

I've tried mentioning it to friends in web dev, but they don't seem to be willing -- if they even look at it, they never try it out. At this point, I just shrug and go back to my simple, reliable and fast pages which load in KB instead of MB...

Is it weird if I still use vanilla JS most of the time? And some jQuery where absolutely needed?

If you're not trying to build an SPA with them, not weird at all. For basic crossbrowser compatible interactive elements, vanilla JS and/or jQuery are/is more than enough. As long as it's easy to maintain, just use what you are familiar with and gets the job done.

We've built SPAs as a part of the larger project using exactly this. Plain JS with a couple of libs that address specific needs (graphics for example). All work fine, simple to maintain and does not require that insane amount of infrastructure.

Can you share some insight about your project? React and redux didn’t happened for no reason. However I think they are too heavy and there are ways to solve same problems with basic tools. Your case may shed some light on to how this can be achieved without react/redox overhead.

>"Can you share some insight about your project?"

Not sure what particular insights. Well here is some example: state management. It is basically split into 2 parts. One part is the actual business object that matters and is a slice of full data on backend. It is a class with methods that take parameters and modify state when executed and broadcasting fact of said modifications so that the UI is aware. Executions of said methods also causing data exchange with the backend using JSON based RPC. Simple example would be Customer with get/set Name/Alias/DOB etc.

Then there are web components and those keep their own state that is limited strictly to presentation issue. For example Currently active form of the application.

It is a big area in general with lots of details and requires way more than a simple post to describe. Unfortunately we do not contribute to open source so can't really share any code.

So structurally the app is fairly simple. Some JavaScript files that are being merged when posting to production and backend server written in C++ accessible through JSON based RPC that can serve thousands of requests per second on single computer with few real cores without breaking much sweat.

This IS weird, because of the jQuery part.

Could you please describe why? jQuery is basically just a bunch of helper functions which makes your JS code a bit more readable and takes away the worry about browser (in)compatibility. Is that bad?

No. It's not bad. As with everything in tech, there are:

1) tradeoffs, preferences, exigencies of use-case

2) devs who conflate their specific use-cases with universal truths

3) fickle winds of fashion affects tech as much as any human endeavor. Right now jQuery is out and React is in

As for jQuery specifically, there has been at least 2 trends militating against it: a wider industry move away from patterns of direct DOM manipulation into virtual DOMs (i.e. using frontend frameworks); and a more widespread acceptance of functional programming techniques while jQuery is inherently "impure"

>"As for jQuery specifically, there has been at least 2 trends militating against it"

Using virtual DOM does not give much benefit if at all on modern browsers.

Functional programming is just one of many existing paradigms and not a silver bullet. One does not need to plug every hole with it.

Of course!

I would note in passing that a description of industry trends is not an endorsement of them. There are lots of reasons for trends beyond pure rational technical strategy.

So far I was fortunate that in most cases I am free to choose the tech stack for the products I make. I pay very little attention to "industry trends" (basically what FAANG tells us to do) and choose what works best for my business ROI wise.

As for developer pool - when I need to hire subcontractor I've never had problems finding one with enough qualifications in whatever area I would need. Btw all subcontractors I've ever had are remote since year 2000

Wow, just looking through that tells me jQuery still adds a lot of value.

That’s a pretty cool site, thank you, I like how it’s very to the point with comparisons.

I'm going to stick with React until web assembly frameworks are common in 5 - 10 years.

As long as it's flagged "Show HN", it's all good. You shouldn't be taking it more seriously than it is. I bet you don't have the same response when someone posts some other pet project of bouncing balls in WebGL and WASM Rust or something.

I've been working as a frontend developer most of my life, so I see what you're saying. Still, it's a just a fun thing to do. I've made some hobby libraries myself with no intention of it "catching on". And even if it's reinventing the wheel, perhaps one of the spokes is improved .

A lot of bloat however, is caused by uptake of the frameworks and having to also support older versions etc.

As long nobody but you uses it you can add/rewrite as needed while keeping bloat to a minimum.

Plus things like performance optimizations; people have been building lightweight alternatives to React for years now, the core concept is not that difficult. Making it performant is the one though.

I do not see this happens with https://github.com/WebReflection/uhtml/blob/master/DOCUMENTA... family. They are around for quite awhile, and their philosophy is clear from start, do one thing well, small and no tooling.

> I've seen this movie several times over the last 10 years.

When you take into consideration other languages and their ecosystems this was happening from the start. It is just evolution. If this lib gets enough traction and goes into the right direction, whatever that may be, it will become popular. Ofcourse chances are small, but..

Most of us watches movies all the time, but without the movie makers there’s nothing for the rest of us to review.

Second law of thermodynamics, sigh


Synergy is my attempt to create the thinnest possible layer of abstraction over the browsers built-in APIs in order to build UIs with Custom Elements. I wanted to be able to express UIs in simpler terms, and I feel like I've achieved what i was aiming for with this. It won't be suited to everybody's tastes, and that’s fine, but I’m having a lot of fun using it myself at the moment and I'm excited to share this for the first time and welcome any and all constructive feedback.

That's the spirit! It doesn't really matter whether this will become the next (p)React, as ling as you learnt something from building it and you are enjoying using it.

And yes, I did create something like this but I wanted to include also a router (like Mithril) and a standardized way to handle state, both global and local... and I ended up with https://h3.js.org -- yep, probably not many people use it but I have been using it for months for personal projects and I keep tinkering to improve a little bit whenever I find I need to polish some rough edges or support additional use cases.

Like others said, I wonder how long it will take for bloat to creep in. For now though yes, I agree that you really don't need much code to build a fully functional SPA. And creating your own micro framework really helps you understand how things really work, without relying on someone else's abstraction.

"Synergy is my attempt to create the thinnest possible layer of abstraction over the browsers built-in APIs in order to build UIs with Custom Elements."

A noble goal. I like that you are avoiding compilation and tooling.

Thanks fergie, glad that you like the approach.

Too bad the name "Svelte" is taken.



In this world of bloat, it is so refreshing to see someone doing The Right Thing.

thanks romwell, glad to hear that you like it!

Thank you for sharing your work. I learned from reading it.

Thanks for the comment, I hope you get a chance to try it out!

I find it interesting, but I'm biased against frameworks because I've yet to see one which claims to support every JS browser, which is one of my objectives.

For example, Opera 12 (Presto) has full modern DOM support with .createElement and such, but I doubt your framework would work with it?

There are hundreds of browsers and engines out there, and I want to support them all. Would your framework degrade gracefully in a browser you've never tested before?

Also, how do you deal no-JS users? I read through the documentation, but could not seem to find one?

Supporting hundreds of different browsers?

This is a noble and audacious goal, but I suspect that it would either take enormous resources, or the least common denominator approach.

OTOH supporting, say, the 3 major browser engines that serve > 99% of the audience is sort of achievable, and also practical.

a) I believe your 99% figure is way off.

b) I believe the remaining 1% matters, perhaps more than the others. (See wheelchair analogy.)

c) Yes, it does take a least common denominator approach at first, but you can build a lot on top of that, carefully, without upsetting even such classics as Netscape, Mosaic, and IE4.

Would you say that one developer working part time for a couple of years is "enormous resource"?

You are going to have a hard time running JS Custom Elements or even the DOM on Mosaic!

IE4 had an early DOM but it was different from the current one, and JS syntax was different too.

Writing DOM-modifying code that does useful things on IE4 as well as on current browsers is possible, but requires a lot of extra code and testing for little gain, and will encounter browser bugs if you do anything complicated, so you can't just drop in a thoroughly-portable framework, you need to test as well.

If what you mean is you'd like graceful fallback to a decent non-JS page on ancient browsers, that's doable, but then it doesn't matter if the JS framework only supports 99% of browsers. Just make sure to disable the framework on browsers too old to use it. (You'll still have a hard time with CSS on Mosaic.)

RE "browser support". Synergy has support for "modern" browsers (e.g., https://caniuse.com/mdn-javascript_builtins_proxy_proxy). It would certainly be feasible to provide a legacy version to provide support for some older browsers. Thanks for asking the question though, I should call out "browser support" in the docs as well as the github page.

Thanks for your questions. RE "no-JS", I have prioritised support for prerendering so that synergy can be used for progressive enhancement. Its early days so the docs are very minimal at the moment, but I will certainly be adding much more detail around this and I'm really happy to hear somebody raising this question as it's a valid concern that often get overlooked.

Synergy looks like "uce" here https://gist.github.com/WebReflection/761052d6dae7c8207d2fcb... But I can see you use "Template Parts" syntax.

Can you explain, what technique you use to update DOM (I'm lazy to walk through code base), is it proxy object like Solidjs, or something like "uhtml". How do you manage to dispose event listener internally (is memory leak possible around that?)


Just read some docs it seems like using Proxy!

Thanks for your question. Yes, that's correct - Synergy uses Proxy to detect change on the object and then simply walks the tree and updates the nodes whose bindings have changed. Yes there is some commonality with µce API due to implementation of the Custom Element lifecycle methods.

This is great!

But, what would you say to those that say, “Great- another year, another JS framework”?

Specifically, why would I want to use this instead of Vue? What does it buy the average developer?

you are not required to use it. And IIRC this is exactly how Vue, riot etc. started their life

its fun, he probably didnt make this for your company/corporation, He made it because he likes making stuff as a programmer.

I find it kinda interesting too so I might try it for my next project...thats how it goes.

That's right, you really have to do this for the love of it when nobody is paying your bills in return. Would love to hear how you get on with it if you do get a chance to try it out.

I love that it has zero dependencies! Is there any chance that typescript definitions will be added, or would you be interested in seeing a pull request?

Yes! That's definitely on the todo list and would be a welcome contribution.

Exactly. I just realized exactly the same. There is no external dependencies in runtime. I think author should add this is as a one of the biggest benefits/features. Congratulations on delivery.

Thanks farynaio, much appreciated.

I really like this project, especially when going through the docs. Nearly all the abstractions are very clean in their approach, the only outlier being the hack of using `#each` `/each` comments to indicate looping. I suppose the HTML specs don't have anything for this yet, so one has to adapt in some way.

I like the docs because, having come from a different dev environment, and seeing web/html as a vast sprawling landscape of surface area to learn, littered with defunt, old, broken, and janky throwaway bits everywhere - the documentation implicitly points out the core path of what's needed to understand how to bind and work with data in a web page.


I'm convinced this clarity comes from you distilling down what exactly _are_ the core pieces, and only implementing them first.

some rambling questions:

I wonder how this (synergyjs) works for a webapp type situation? Would one extract .js scripts as modules to reuse custom components? or is that trying to bring this into a more complex setup than is the sweet spot for this lib? e.g. is this better suited for a page at a time?

Also, maybe I'm dense, but does this approach lend itself to single page apps? My understanding is it shines when you have single pages with some logic behind them. If you need to jump to another page, the "passed data" would be encoded in the url, yes?

(I seem to recall the html 5 standards were looking to add something (was it 'proxy'?) that was something like frames, but involved web components, and maybe even passing of data through slots... is that a thing?)

Hi mjgoeke, an update RE the "hack of using #each", synergy is now using <template each="item in items"> since v2 (https://synergyjs.org/repeated-blocks). Much less hacky, and has also saved a few more bytes from the overall package size.

RE: Would one extract .js scripts as modules to reuse custom components? Yes, you can certainly do that. the define function supports both template element nodes or strings, so you can work directly in a HTML document (the web will be getting HTML imports before too long) or do it all in JS and publish to NPM.

Thank you, much appreciated. Yes, there are proposals for native templating, but i suspect it will take some time to agree on such things. I opted for comments in the end mainly to support multiple top level nodes, but they also prove helpful for place-finding when inspecting the DOM.

How does it compare with Preact?


I tried Preact a few weeks ago and the examples all worked, which was nice. And there's no build step -- you can develop with a CDN and hit F5. Big win IMO.


Preact is a really great project! I contributed to this myself in a very small way last year to add support for customised built-in elements. I would definitely recommend Preact if you're a fan of React. Synergy is different in a few ways, for example it uses Custom Elements whereas Preact has its own component system just like React. Synergy also separates HTML and JS concerns more clearly, making it a little more like Vue in that respect. Preact and Synergy both share this ability to work "as is" directly from a CDN without any heavy toolchain.

I use Preact. I like it a lot. Started with pure ES6, Preact, and htm templates - no transpilation step! As the project got bigger I migrated to Typescript and start using it's built-in JSX compiler. Was a pretty easy step. My only package dependencies for a long time were preact and preact-router. Recently moved to webpack to support proper packaging of node modules when I moved from REST to GraphQL. But no babel, and it's been really nice to slowly increment the build complexity only when it's been needed.

Preact is (or was at one time) a nearly-complete implementation of React's APIs -- meaning a virtual DOM, etc. Synergy takes its own approach, and uses Custom Elements (from the "Web Components" standard).

Edit: and synergy is also optionally avlbl via CDN for the no-tooling approach you liked in your preact experiments.

I'm using Preact now in building a widget to be used on third party sites. I didn't want the heft of react, but yet that is what I knew well. Enter Preact. It has been fantastic. I've basically used all my react knowledge without any of the weight of React. Kudos to the Preact team.


> And there's no build step -- you can develop with a CDN and hit F5

Same with React. There is a production CDN https://reactjs.org/docs/cdn-links.html

Not totally the same as React as you still need to transpile JSX in most scenarios. I suspect that’s what they’re getting at.

You can write react without building or jsx, it's in their tutorial or getting started doc.

That's why I said "in most scenarios". Every React codebase I've ever worked in has used JSX.

Just because "Every React codebase I've ever worked in has used JSX" doesn't mean "you still need to transpile JSX in most scenarios". Of course, if you're serious about using React, doing the transpilation before pushing your code to the CDN probably makes the most sense, rather than doing the transpilation client-side or using vanilla JS. But just because it's common, doesn't mean you need to follow that way of doing things.

You just admitted that "it's common". That's another way of saying "in most scenarios". I don't know why you're splitting hairs like this.

Ah, then it's similar to Vue (for that particular feature)

Skimmed through the docs. Some thoughts:

- it has a bunch of useful serialization sugar (e.g. `{{ classes }}` serializes correctly whether it's an array, an object of booleans, etc. This is similar to Angular (in React-land, this got pulled out into a separate package, classnames). There's similar sugar for `style` and objects (which React also supports).

- I'm not a fan of the variadic event handler signature. If I understand correctly, having a event handler inside a loop adds an extra argument to the handler function, but what happens if there are nested loops? In React-land, this would be done w/ arrow functions and closures; in Angular, one would write a js function call similar to plain HTML event handlers. I prefer the React approach (though I understand that isn't really an option for the way you approached synergyjs)

- Similarly, if `#` is bound to loop index, then how do you access outer loop index in a nested loop situation?

- Binding view property names to form controls of the same name is an interesting abstraction. React looks clunky in comparison (yes, even hooks). Angular has a similar facility, with the addition of allowing custom transformation logic (think getter/setters for bidirectional bindings).

- prerendering via a browser-like environment isn't the best approach IMHO (I've seen people run into issues w/ jsdom missing features, for example, and something like puppeteer is a bit of a heavy thing to be running frequently server-side)

- I like the clear separation between JS and CSS (but, then again, I'm an old school person). React people might dislike it if they're used to css-in-js per-component style encapsulation.

Overall impression: appears to pack quite a punch for 4kb (more so than Preact IMHO, because of how it handles forms). Docs are clear and to the point, but could use more examples/tutorials (especially lifecycle hooks). Would like to see it mature a bit (e.g. in terms of addressing things like nested loops, as mentioned above), and I think it would benefit from considering a less expensive SSR approach.

Very promising!

Firstly, thank you so much, this kind of feedback is extremely useful and greatly appreciated. I'll try to reply separately to each of your points for clarity...

RE the event signature: (If you raise an event from an item within a repeated block then synergy provides the data for that item as the second argument to your event handler function.) If you have a nested loop then you'll get the data item for that particular loop.

Right, sorry I think I wasn't clear. I'm wondering how one goes about something like this

    as.map(a =>
        bs.map(b => <td onClick={() => foo(a, b)}></td>)
Notice how both `a` and `b` are passed into `foo`. There are other possible permutations, such as passing indices or properties of items. I believe it's possible to access `b.bar` easily enough, but it wasn't clear how to access `a` or the index of `as.map` from inside the inner loop.

see the comment above "RE: #" concerning the index. synergy doesn't provide means for you to pass custom arguments into the event handlers, but the event target and the datum provide context of the loop and the handlers "this" is the viewmodel itself.

So then one would do `function foo(e, b, a) {...}` to access `a`?

Apologies for the late reply, finally I had to get some sleep! No, you only get the datum for the loop from which the event is raised.

RE css-in-js style encapsulation: One of my goals was to support pre-rendering, which is why Synergy doesn't currently use Shadow DOM. In the (hopefully near) future, Shadow DOM will become declarative and at that point Synergy will adopt whichever pattern the web lands on and be able to provide both features.

RE separation of concerns: Glad you like it, and yeah - the react approach is very popular so this won't suit everybody, but that's fine...people have different styles and I don't believe there's a one "right" way any more than there's a "best" programming language.

Re the '#', yes - this is currently a limitation and will be addressed, most likely with destructuring syntax for the repeated block declaration (e.g., #each [i, item] in items)

RE prerendering: yes, completely agree - puppeteer would certainly be heavy for dynamic SSR and I wouldn't suggest that. Perfectly suitable for build-time prerendering though, which is what I've been focused on so far in this area with Synergy.

RE docs: Yes absolutely! The next section in the docs will be tutorials and all of this great feedback will be most useful in helping figure out what to focus on so thanks again.

I used Milthriljs a few years back. Also created something similar with the goal is to create a "thinnest layer" for building UI.

What I realized is, "who would add something unnecessary anyway?".

I mean developers would think of keeping it as thin as possible. Just that over the time, we run into senarios that need extra codes. Otherwise, users would think about alternative solution. And in web development, it very likely to happen

Hope that you work out the real competitive advantage

Mithriljs is great, I used it even before using Reactjs and it's the easiest UI framework ever.

Thanks, marketing certainly isn't my greatest strength and things can always be read in more than one way so I will keep that in mind.

3.8KB over the wire and 9KB uncompressed. That puts it in very similar territory to Preact. That's pretty good. I'd rather use Preact because that gives me access to the React ecosystem, but this is definitely worth considering if you don't need any other resources.

Just noticed there is already existing another Synergy framework and "Synergy" package. Probably better to rename the library to avoid confusion.

By the way, in terms of bundle sizes React is smaller and Preact is almost the same. But I think the reason is that react-dom is not included into calculation https://moiva.io/?compare=Synergy+preact+react+synergy+vue

Thanks for your comment. The synergy you're look at there appears to be "@onenexus/synergy" rather than "synergy". It's a shame that the comparison doesn't use the actual package name to avoid such ambiguity. If you look again at the moiva link, the results show "synergy" at position 4. Hope that helps to clarify.

I mean there are 2 npm packages now - synergy and Synergy https://www.npmjs.com/package/Synergy Moiva.io shows names of npm packages

well, there's only one "synergy" that you can install from NPM, etc, but yeah - it's crazy that NPM site is working in that way because the other project has a project name that doesn't match its package name. I'll be sure to raise a ticket for that this afternoon so thanks again for pointing it out!

As time approaches infinity it will be harder and harder to find unique project names...

I'm sure we can keep adding names...this project can be SynergyExcelsior

))) How about SynergySuperior? ;)

Here's a rough video demo showing a simple "hello world" component: https://www.loom.com/share/ffe3fb6d23264cc7ad458f6b856ddc49

That's super cool! I can see myself using this to add dynamic content more easily on server side rendered websites.

awesome, thanks Xevi! would love to hear how you get if you do get around to that.

This looks surprisingly well documented for such a tiny project, and reasonably complete for such a tiny runtime. Nicely done! :)

Thanks so much for your comment, much appreciated.

I don't understand when people complain about Yet Another Framework. There isn't a single solution to everything.

When there are plenty of unknowns and you're working solo, you need a very thin layer that lets you craft a prototype quickly and not spend too much time configuring or generally investing a lot because it's something you plan to keep for a short time anyway, or it has a small scope that is never expected to grow. I think this framework kind of fits this model.

In a corporate environment, on the other hand, you're probably building something with the intention to last and then you need something that is established and has rigid interfaces, off-the-shelf components and Stack Overflow activity. Ideally, a framework that can only produce one style of code so that the next person or the next team can pick up.

Another possibility is you're on a budget, a handful, but know-their-way, developers and there is no plan to scale that for the foreseeable future. You want to try out ideas and be able to fail quickly. If you use React and TypeScript for your prototypes, you'll get a sound and solid codebase but also one that also cost you a lot of time. So, if just before the end and a couple of months in you discover you need to do some dramatic changes, you are left with little options and an empty budget.

Each needs to do their research and decide based on their unique requirements and more frameworks = more options, easier to find a fit. In my opinion, use the big frameworks only when you have a clear concept of what you're building. Otherwise, use something that gets the thing done as painlessly as possible.


In addition to that, the world changes, and our concept of what is the proper way to build UIs or even what constitutes a good UI changes, as the world and the people change and new technologies emerge. If we aren't exploring ideas at the edge of our undestanding and knowledge, then we'd still be writing <font> tags in our Geocities pages.

"There isn't a single solution to everything". Amen to that. Some libraries suit peoples ways of thinking more than others in the same way that some people like Java and others like LISP.

Looks nice. Svelte is also <4kb, but it is compiled.

I also feel that Svelte has taken the best of many worlds.

Most front-end Javascript frameworks rely on either declarative widgets or some contrived implementation of HTML / CSS with a build step to get the developer's code to render in the browser.

Svelte's approach to sticking extremely close to traditional HTML / CSS & JS, and then compiling everything together, in my opinion, makes it much more approachable and maintainable.

I think Rich Harris is to front-end as John Carmack is to games development, and no doubt Svelte is a marvel of technology, however I dispute the notion that it is more close to "traditional html / js / css" than either React or Vue. For example, most frameworks use webpack which extend es6 module syntax in a way that they don't work natively in the browser without compilation, and I don't think Svelte is any better than them in this regard.

Svelte also feel a lot like using Knockout which was/is great (although its not a full framework)!

Would be also interested in a deeper comparison to Svelte here.

Thanks for your interest Mizzao. Svelte is a cool project, and the discussion RE buildtime vs runtime raise some great questions RE trade-offs. What I would say is that neither project would be the right choice for every use case. Svelte is very feature rich and provides more of a “batteries included” framework approach, whereas Synergy has a much smaller feature set and scope which leaves flexibility and choices in other areas. In this sense, Synergy is easier to compare feature-by-feature with a library of smaller scope such as Preact.

You should work on your landing. I really appreciate the idea and I personal feel the minimalistic design you have behind this concept and the landing page it try to promote, but still the page should be a little more wow (it's complex and fast) and the description is so minimal, and this make me wonder what can I build with this framework.

Thanks for the feedback. Yes, there's lots of work to do to make the docs "complete", not least some decent tutorials. It certainly isn't the "finished product" but I'm really glad that I decided to share it here on HN as the feedback is going to help me a great deal to understand where best to focus my efforts.

Hi, how is your project different from alpine.js?

For the record - here they are alpine.js (https://github.com/alpinejs/alpine) and synergy.js (https://github.com/defx/synergy) repos.

Thanks for your question. I'm not overly familiar with Alpine but yes, the syntax is very different. Alpine appears to freely mix JS and HTML whereas Synergy minimises this in favour of a clearer separation of concerns.

alpine syntax looks very different from a quick glance at the readme.

very angular-ish, template heavy with it's own syntax.

Alright, just checked it out. Using regular HTML comments for rendering many items is neat and using the hash symbol to display the index is genius. I really like that.

Now I just need to find a project to use this on.

awesome, thanks! Would love to hear how you get on with it.

Shoutout to Barleytea which was posted a few months ago, which is also an alternative that comes in at 3.1kB MAX (if you opt-in all the features) AND, more importantly, comes with a great design document / explainer / framework builder.

I have no affiliation, just happened to notice it and really really like its philosophy, framework builder, readable code, and documentation.

I hope Andrew sees this comment so he can chime in.


Nice work, perhaps this has its niche. However, for general front-end development, I'm wondering about what are core advantages, over, say, Vue (simplicity is the only aspect that comes to mind off the bat). Considering that the size is not a huge advantage (gzipped and minified Vue 2/3 is just ~20K and even with Vuex and Vue Router is ~30K) and that Vue's large and diverse community and ecosystem makes it super attractive versus non-major alternatives ...

That's really nice! I like it. I also built a minimalist ui tool a while ago [0] so I totally understand where you are coming from. Mine never really took off probably due the lack of interest of minimalism at that time, but there may be a wider audience for that approach nowadays.

Are you using it in a project of yours?

[0] http://celebio.github.io/Yama.js/

I love that demo that automatically types and renders the result, have you made a library for that? It looks like a small custom script.

thanks! yes it's a small custom script

Thanks, glad that you like it, and I love the fact that Yama "fits in a Commodore 16"...

preact (https://preactjs.com/) is 3kB...

And React is only about 5kB unless I'm mistaken?

React itself is quite small but react-dom is much bigger: 121KB minified, 40KB gzipped - https://bundlephobia.com/result?p=react-dom@17.0.1

I see, that number came up in search but I did suspect it wouldn't be the full story. Thanks!

Jesus, that's jQuery levels of obesity.

I'm curious why less features is a goal here? I wish VueJS had more features, or at the very least more tooling. Vue has progressed a lot but there is so much more room https://github.com/vuejs/vue-devtools

Few questions: Have you compared the performance? With others (React,Vue etc) Is it compatible with minification? Nothing breaks? Better than the others in managing live dom elements?

Hi jeerovan, thanks for the questions. RE "minification": yes, - there's a minified version (terser) as part of the build and it should also be compatible with closure compiler. RE "performance", no I haven't made any comparisons using benchmarks, if that's what you mean. DOM updates are batched together using requestAnimationFrame and the update cycle walks the tree to perform the updates, so that should give you some insight into the trade-offs. RE "better than others at managing live DOM elements": better in what sense?

Looks like this uses a templating pseudolang with html comments. I had hoped that we were leaving that behind

Fair comment. Approach to repeated blocks is something I wasn't sure about, but synergy is now using <template> since v2.* (https://synergyjs.org/repeated-blocks) so no more pseudolang ;)

Isn't it LitElement reinvented?

Hi lolive. In one sense, yes! Synergy and LitElement both seek to achieve the same primary goal, which is to make it easier to work with Custom Elements. Aside from that, the two projects are quite different in their approach.

In their technical approach? Could you elaborate on that point?

I haven't looked too closely at Lit source code recently so I couldn't really comment on that but, from a high level, they differ in the sense that lit uses render function (like react) that mixes HTML/JS whereas synergy separates the two between view/template. Neither is better or worse of course, its all about trade-offs and preferences. Lit elements are described with classes whereas synergy uses factory functions. Lit uses Shadow DOM by default, whereas synergy makes it optional.

That’s a very nice summary. Thanks for this clarification.

This looks like https://github.com/Freak613/stage0 combined with custom elements.

FYI, I wrote something similar a couple of years ago but never took the time to publish a repo...

This is a very cool experiment and possiby a tool. I have nothing to comment on custom html elements, binding or flow but templating engines always interested me.

I like how your templating language is minimalistic (not embedding whole js syntax inside) and is valid HTML (could be prepared using HTML authoring tools).

I have few remarks comming from my expeirinece in wirting and using minimalistic templating engines.


This templates tightly integrate with html and magically interpret the view model values depending on the context they are used in html.

I think it could be better to explicitely indicate in place of use that the value will not be used directly.


    <div hidden="{{hide}}">

    <div :hidden="{{hide}}"> 
    <div _hidden="{{hide}}">
    <div :hidden="hide">
This would make it explicit, aria would not need to be an exception and HTML and your syntax would be clearly separated. You could just pass argument through funcion named `hidden` (or `class` or `style`) and even make whole thing pluggable with custom functions that preprocess the argument into the attribute. (Or even multiple attributes if necessary).


Passing current item from `#each` loops into event handlers implicitly is very cool, but you might want to think about what if you have nested loops.

Maybe it would be cooler to pass not just the element but sort of `context` object that contains current elements of all nested loops and perhaps some other stuff in the future?

Also you might consider passing it not only into event handlers but all functions called from template.

Again you could use `:onclick` instead of `onclick` to indicate that there's some additional magic happening.


You might want to consider making loop variable optionally anonymous to reduce the noisiness of looping.

    <!-- #each in people -->
    <li>Hello {{ .name }}</li>
    <!-- /each -->

You could do form binding though `:name` to indicate that something beyond just usual HTML is happening and allow people to opt-out for some controls by using just `name` instead of `name`.


All of this could easily work with pre-rendering and hydration by not removing `:something` attributes when `something` function is called to do the appropriate magic.

RE "Also you might consider passing it not only into event handlers but all functions called from template": By design, there's no support for calling functions from templates other than via event handlers, or via getters (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...), which are treated just like any other property as far as the template is concerned.

Thanks Scotty, your feedback is greatly appreciated! Yes - with nested loops you simply get the datum for whichever block item raised the event, nested or not.

What I meant was that sometimes in the handler you might need datum both for the item that the handler is in and the item of the surrounding block (or even blocks).

    <!-- #each row in rows -->
    <!-- #each field in row -->
    <td>{{field}}<button onclick="edit">...</button></td>
    <!-- /each -->    
    <!-- /each -->
`edit` might need both row and field to perform the edit, and even possiby # of row and # of field.

So a richer context passed to handler might be useful.


Regarding not calling functions from template by design it's all good, but you might consider introducing the ability to call some functions (through html attributes prefixed with : or _) during template interpolation.

Those could be plugins of your templating system that perform some operations (like generating attribute "hidden" or not depending on boolean argument, or binding form field to view model, or binding event handler, or something else).

Those functions might benefit from knowlege of template context they were called from (for example handler binders might want to pass this context along into bound handlers, like you already do with current item and your built-in handler binding solution).

I understand that this a bit different from what you made, but by extracting all of that functionality into separate self-contained functions exposed to the user, instead keeping it as integral, internal part of your template interpolation process, you could do yourself a favor. Because people who are missing some funtionality you haven't thought of yet might implement it themselves easily. This might increase usage of your framework and contributions from users.


Those are just some ideas where you might go further with your templating engine while keeping it simple. I hope I communicated them clearly enough, but if not and you are interested, please ask.

Thanks Scotty, you communicated these ideas very clearly and this all makes perfect sense to me. One of my main goals with Synergy is simplicity, which in the context of this discussion would mean a lower level of configurability / customisation, so pulling that template functionality out and moving decisions on to the user would (as you say) take the design in quite a different direction. A perfectly valid direction though, and one that would doubtlessly better suit some folk more than my approach - I'd love to see you fork Synergy and implement these ideas!

Not to talk you down, it is never-the-less good thing to build things.

But claiming is as alternative is overblown, people choose those two frameworks because the rich ecosystem and support behind it, for which, except probably Angular, there are no way around them.

Thanks karmasimida, you're right; synergy is in its infancy and it has zero ecosystem or community, so when I say "alternative" the context is purely limited to synergy being an alternative approach to building UIs, that's all :)

Looks easy to use. Is it possible to use with server side rendering?

Yes, you can prerender in a browser (e.g., using Puppeteer) or provide a synthetic DOM (e.g., JSDOM) in Node. It's the next thing on my list to flesh out some more detail in the docs around this.

Thanks for working on this a sharing it public. Keep going.

You are more than welcome and thanks for the words of encouragement imvetri!

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