←back to thread

94 points thepianodan | 10 comments | | HN request time: 0.001s | source | bottom

I had a mind-blown-moment when I learnt that Obsidian was built without any frontend JS framework. ( https://forum.obsidian.md/t/what-framework-did-the-developer-use-to-create-obsidian-desktop-application/30724/11 )

The benefits, I can see.

    JS frameworks move really quickly, and when we're working on a large, long-term project, it sucks when big breaking changes are introduced after only a couple of years. Sticking to slow-moving web standards (which are quite mature by now) increases the longevity of a project.

    And the stability also means that more time is spent on delivering features, rather than on fixing compatibility issues.

    There is also the benefit of independence. The project's success is not tied to the framework's success. And it also makes the project more secure, from supply chain attacks and such.

    Because there is no "abstraction layer" of a framework, you also have greater control over your project, and can make performance optimizations at a lower level.

    I feel not using a framework can even make us a better developer. Because we know more of what's going on.
There are benefits to using frameworks too, I'm not here to challenge that.

But this alternative of using none... it seems rarely talked about. I want to learn more about building large (preferably web-based) software projects with few dependencies.

Do you have any suggestions on how to learn more about it? Are there any open source projects you know which are built this way? It needs to be large, complex, app-like, and browser based. I'm more interested in the frontend side.

Thank you!

Show context
Octoth0rpe ◴[] No.45615334[source]
> JS frameworks move really quickly

React is a lot more stable than I think you're giving it credit for.

> And the stability also means that more time is spent on delivering features

Frameworks/libs also exist to save you time, thus letting you spend more time on delivering features. And fwiw, the obsidian team seems to agree in principle. Your link goes to a forum post of some kind, in which one may find a link to obsidian's third party deps: https://help.obsidian.md/credits#Third+party+acknowledgement...

These do not include React, but do include:

- i18next - lezer - moment.js

Plus a bunch of others. Why didn't obsidian write their own date lib and chose to use moment.js? Because it saved them time, despite the fact that moment.js does make changes, and many people are moving on from it in any case.

The idea that not using a frontend framework will let you focus on delivering features seems reductive, and the obsidian anecdote doesn't support the idea anyway.

Whatever you're building, it's never a bad idea to deeply understand the tradeoffs that using a library will bring. Obsidian probably couldn't accept the downsides of React due to them needing a bunch of custom renderers for content, which React makes harder. But that is likely a rare constraint for apps in general.

Generally speaking, libs like react exist to save you time and help you focus on delivering features.

replies(4): >>45615472 #>>45615480 #>>45617852 #>>45618677 #
1. lloydatkinson ◴[] No.45615472[source]
> React is a lot more stable than I think you're giving it credit for.

A lot of the HN zeitgegist would have you believe React is the opposite, sadly.

replies(1): >>45615677 #
2. CaptainOfCoit ◴[] No.45615677[source]
The React ecosystem moves really quickly, and likes to re-invent wheels.

But React core APIs remain relatively stable, I've been using React the same way for many years at this point, and you can ignore the parts you don't like, like I'm ignoring hooks and haven't found a single use case where I needed them.

replies(1): >>45615807 #
3. adithyassekhar ◴[] No.45615807[source]
Could you please tell me how are you avoiding hooks? You're not using useState or useEffects?
replies(3): >>45615819 #>>45615859 #>>45619077 #
4. CaptainOfCoit ◴[] No.45615819{3}[source]
I mainly use React via Reagent in ClojureScript, and literally have no use cases where I need to use useState/useEffects for anything.

Turning it around, what exactly are you unable to do without useState/useEffects?

replies(1): >>45616178 #
5. Octoth0rpe ◴[] No.45615859{3}[source]
class components (which do not use hooks) are still supported by React with no scheduled deprecation AFAIK.
6. adithyassekhar ◴[] No.45616178{4}[source]
When I want to memoize something slightly complex, for simplicity's sake let's say sorting an array of objects based on one of it's keys. I can put that in a useMemo and it won't sort it again when the page eventually rerenders for some reason.

Usually that array is mapped elsewhere and those child components might also re render if the array is recalculated.

useEffects are when I need to call something outside of react, or when the page gets mounted or I need to call a function when something changes.

I'm still fairly new to this, the above examples may scream bad architecture to those more experienced, all criticisms welcome :)

replies(2): >>45618345 #>>45624133 #
7. Octoth0rpe ◴[] No.45618345{5}[source]
> all criticisms welcome :)

No criticism really. Your useMemo example is the right use. Your useEffect use is fine, but for things like api calls (which 'call something outside of react' may refer to), you're often better leaning on something like react-query, which is of course built on top of useEffect. So still the right tool, but let others handle many of the sharp edges around that problem.

replies(1): >>45622694 #
8. homebrewer ◴[] No.45619077{3}[source]
One of the projects I sometimes work on uses class components + mobx; it runs circles around hooks in speed/debuggability/convenience IMHO.
9. adithyassekhar ◴[] No.45622694{6}[source]
Thanks. I've started with rtk and saga hence the useEffect. I've since moved to rtk query.
10. Our_Benefactors ◴[] No.45624133{5}[source]
> I can put that in a useMemo and it won't sort it again when the page eventually rerenders for some reason

useMemo dependency smell. This is almost always because your dependencies are wrong. This can often happen if you put a dependency as [object] instead of [object.field] due to how JavaScript maps objects to memory.