Thibault Maekelbergh

📦 Why is module distribution so complex?

Here is something that has been on my mind for a while and that I find very tedious to try and remember when coding in different languages. I really like to write Typescript, Python, Bash, Go, and sometimes even Ruby...

But why are all their module distribution methods so different and hard.

Typescript


Javascript/Typescript is beginner friendly. It runs almost everywhere these days, does not restrict you even when you apply bad coding patterns and the Node ecosystem is advanced. But maybe too advanced?

Suddenly NPM comes into play, it is part of Node but not really. It can be versioned/installed separately from Node, but also comes pre-bundled when you install Node. There is also Yarn for some reason. It uses lockfiles to pin down dependency versions, but it comes in 2 version formats (lockfile v1 and lockfile v2) where the v2 is suddenly super restrictive.

Publishing to a registry requires a good set of knowledge about the NPM ecosystem and its versioning. Modules distributed via NPM are tediously large and NPM is still somewhat slow compared to other module installation toolchains.

Python


This is a disaster. I still can not begin to grasp how people invented this flow to publish a module. I actually have to keep a document in my Notion workspace titled How to publish Python packages in order to successfully publish one. And I have to reference it each time.

There is Python 2.7 and Python 3. Luckily Python 2.7 disappeared a while ago but not so long ago you had modules that were incompatible with 2.7 and those incompatible with 3 forcing you to remember which module is compatible with which Python version. Then there is pip, the CLI interface to the PyPi registry, BUT WAIT THERE IS ALSO easy_install which comes with Python but pip also kinda comes with Python. Oh yeah, and there was pip which if your shell was set correctly aliased to the Python 3 version of pip. But there was also pip3, pip2, and pip2.7. Yes, very easy to grasp.

Then there are also multiple types of modules: wheels & eggs. Both are still available on the public registry. I still have no clue why they differ and why 2 versions exist. I just want a module.

Want to publish a module? You also need to install wheel, twine and setuptools. Oh and make sure to publish to the test registry first and to execute this monstrosity of a command:

type: embedded-entry-inline id: 5U5IKiAkWOXhMH9dcr5jxr

That is a lot of context and not easy to remember. Oh, and there is also Poetry which is admittedly a little bit better but it is again an extra tool serving the same purpose. I have the same problem with Yarn and NPM.

I already find the Python ecosystem very harsh and difficult for newcomers when coming from friendlier ecosystems like Node and Javascript. I gave it a go and published a Python package for interacting with the VRT APIs but I found that process so exhausting, that for other ideas of publishing modules I just gave up and abandoned them or kept them private for myself. The difficulty of publishing to PyPi is effectively what is holding me back from contributing more to Home Assistant because they use Python modules.

Bash


Where to start? I love the language but I hate it so much at the same time.

I love that it is the backbone of various programming languages, infra, devops, and CLI tools and that it just works on any OS/system.

But I hate that it is a complex language with unfriendly syntax and a lot of quirks. It behaves differently if you run it with macOS BSD Bash versus Debian GNU Bash. Version 5 has good additions but almost no one has that on macOS.

And then there is the fact that modules do not even exist in Bash. The only thing coming close to a module is sourcing another Bash file which will also execute all non-function code, so kinda dangerous. The only thing I have ever seen making an attempt at distributing a Bash module is hassio-addons/bashio but then again it was also made for the purpose of serving an existing project rather than public open source.

I would love for Bash to have some kind of module/script distribution. It would make it very easy to integrate custom scripts in Python, React Native, Go, and Docker projects. Your only option here is the commonly seen interaction with wget/curl piping a zip file or script to bash for evaluation but I find that to be more of an attempt in vain.

Golang


I am still learning a lot about Go and their module system is in flux, changing a lot between newer Go versions. But Go is one of the only languages that seem to be tackling the module distribution problem well.

There is no separate module manager, you just install the Go runtime to write/run code and you can also install modules. No need for different lockfiles, just go.mod and go.sum which you do not need to worry about a lot thanks to go mod tidy.

The best thing here is that you do not need to worry about registries and stuff like that. You just install modules from github or another remote url that hosts Go source code. If your code compiles (which Go is luckily restrictive about) your module is usable by others.

It will surely have some things missing, but I have yet to discover them. There was no mental overhead here. I could install go and download a module, implement it in my code, compiled it, et voila: working software. I hope other (or newer?) programming languages follow this example because it seems like the way to go.


Other opinions? Am I jumping to conclusions? Glad to hear those on Twitter @thibmaek!