Third-party libraries in extensions

Are third-party libraries allowed in extensions on extensions.gnome.org?

I want to use RxJS, which weighs ~285kb in non-minified form. Will my extension pass the review if it will load RxJS?

I already use RxJS, but in an external gjs process only.

This section of the review guide looks relevant:

Reviewing Python modules, HTML, and web JavaScript dependencies is out of scope for extensions.gnome.org.

as well as

Extensions may install modules from well-known services such as pip, npm or yarn but MUST require explicit user action. For example, the extension preferences may include a page which describes the modules to be installed with a button.

285kb certainly sounds like a lot of additional code that would have to be reviewed if included directly …

1 Like

Reviewing Python modules, HTML, and web JavaScript dependencies is out of scope for extensions.gnome.org.

What does the word “web” mean here?

If I’m importing RxJS in GJS code, does it count as a “web” dependency? Do I have to invent some kind of “installer” with dynamic import for it?

For example, the extension preferences may include a page which describes the modules to be installed with a button.

My “Preferences” dialog itself imports RxJS…

You can mention the dependency in metadata description:

This extension depends on RxJS. You can install it with:
npm install rxjs

In that case, you don’t need to create a UI to ask users to install that.

I have a script that checks gi dependencies, and shows a message if something is missing, with the list of packages to install (it is smart enough to correctly find distribution-specific package names, yes). And still I receive messages from users who can’t figure out how to do that.

Based on this experience, I belive adding npm command to the description won’t work.

Do you really need all 285kb? Could the library be replaced with some small utility functions?

I’m using 13 rxjs operators, 3 classes (subclassing 2 of them multiple times), and a few trivial utility functions.

I’ve tried to measure coverage. After a quick test, line coverage for rxjs is: 29.2 % (1210 / 4142), function coverage: 22.9 % (200 / 873)

So, yes, I’m using only ~30% of the library code. But it’s still more than 1k lines (non-comment, non-empty lines). My extension itself is about 5k lines of JS code, according to cloc (and about 4k of them rely on rxjs).

That is interesting you were able to get that usage out of it in an extension, when nothing else in gnome-shell or gtk supports it. I have thought at points in the past that gjs should include some way to use RxJS as a wrapper for gobject signals, as the concept of it is very similar…

It requires only a bit of glue code to be usable together with GObject/Gtk

1 Like

The two real issues here are security/stability and volunteer time.

For better or worse, the user community has decided that anything that goes wrong with extensions is “GNOME’s fault”. This is really why the review process evolved from a quick once-over, to a thorough review for security, stability and privacy issues.

Even if our reviewer(s) had the experience to identify bugs in third-party libraries, time is a very real constraint and allowing them to be included in extensions will really open the floodgates. Using a third-party library to save time is not an issue, it’s just required that the responsibility for any problems be a contract between you and the user.

The only way to really do that is to have any third-party code installed separately from what it is distributed from extensions.gnome.org. As long as it’s made clear what the user is agreeing to, there’s really no rule about how you request permission from the user. It just has to be an explicit and informed decision the user makes.

1 Like

Versions of my extension, published on extensions.gnome.org, already include bundled RxJS, it’s just not loaded by the shell extension itself, only by external GJS process.

Also, in the same way, handlebars.js is bundled and used.

Does it mean these versions should be removed? Does it mean I shouldn’t upload any new versions until I get rid of third-party libraries?

RxJS is bundled since July, 2022. Handlebars - since November, 2020 (all versions of the extension).

If those have been accepted already, I’m not sure :slightly_smiling_face:.

Probably @jrahmatzadeh was the reviewer (since he usually is these days), so I’ll let him chime in. He may have noticed it was not loaded into the shell, where it could affect the core experience and have more serious consequences.

If ddterm is the extension, yes, it’s not getting used inside extension.js as mentioned in this review.

But I still don’t like shipping that inside the package. It’s really hard to review and the code can leak to extension.js just by missing one import line in future reviews.

And about handlebars.js in ddterm extension. I think that was the one I had to download the original and compare the minified version. I believe that was the reason for adding non-minified rules to the review guidelines.

Anyway, that would be nice to remove both handlebars and RxJS and use what gjs offers instead.

1 Like

Handlebars: I can’t find any comparable text templating functions in GLib/GJS. imports.format can’t even reference parameters/variables by names, not even talking about the rest of the syntax…

RxJS: with RxJS I can write “connect to this signal of an object referenced by this property”, as one expression, and it will automatically disconnect and connect to the new object when the property changes. With raw GObject I’ll have to write connect/disconnect manually (not only in property notify handler, but also in constructor and destruction), store the handler id somewhere… And it’s just one of the use cases.

Another example: automatically connect to a signal/bind a property when some value becomes true and disconnect/unbind when it becomes false. One expression in RxJS, multiple operations in raw GObject/GJS.

I’ve constantly had more bugs when I worked with raw GObject signals/properties.

Would it be any better if I wrote my own 1000-line “mini-RxJS”?