Joplin as a project is becoming complex enough that I believe that instead of implementing new features for the time being, it’s time to start hard-coding in core features that Joplin needs to function properly instead of relying on third party libraries as much as it does. Due to the licenses of many libraries that Joplin uses being under MIT, simply copying from some of them directly into the Joplin source tree, along with their licenses and copyright information should be plenty as long as their dependencies don’t have some weird clauses or license issues. If this isn’t possible or viable, an alternative could be to bundle known working library versions together the same way that Unreal Engine does it and only require downloading and extracting them into a dependency directory when building from source. That way when a library updates upstream through npm, we don’t have to worry about having as high of a chance for breakage to appear. Npm is convenient but also isn’t necessarily going to keep Joplin stable long-term.
Hard-coding dependencies makes sense and we already do this for some of them by pinning the packages. Essentially it means that we explicitly set the version number, so even if the package is upgraded and breaks, we won’t be affected.
Copying the dependencies to the repo wouldn’t be practicable because that’s thousands of small node modules files that we’d need to add. Upgrading them would also difficult, so it’s better to let npm handle this automatically.
That being said, there might be a case to pin more packages, or even all of them. We’d need to research a bit the pros and cons of doing this though.
It would definitely be good to figure out which ones don’t need to be upgraded and locking them in. Also, dependencies that end up being single file libraries could possibly be ones that just get directly implemented into Joplin.