Announcement: pychub is released, along with hatch, poetry, and pdm plugins!

Hey fellow deveopers!

I built a packaging tool called pychub that might fill a weird little gap you didn’t know you had. It came out of me needing a clean way to distribute Python wheels with all of their dependencies and optional extras, but without having to freeze them into platform-specific binaries like PyInstaller does. And if you want to just install everything into your own current environment? That’s what I wanted, too.

So what is it?

pychub takes your wheel, resolves and downloads its dependencies, and wraps everything into a single executable .chub file. That file can then be shipped/copied anywhere, and then run directly like this:

python yourtool.chub

It installs into the current environment (or a venv, or a conda env, your call), and can even run an entrypoint function or console script right after install.

No network calls. No pip. No virtualenv setup. Just python tool.chub and go.

Why I built it:

Most of the Python packaging tools out there either:

  • Freeze the whole thing into a binary (PyInstaller, PyOxidizer) — which is great, until you hit platform issues or need to debug something. Or you just want to do something different than that.

  • Just stop at building a wheel and leave it up to you (or your users) to figure out installation, dependencies, and environment prep.

I wanted something in between: still using the host Python interpreter (so it stays light and portable), but with everything pre-downloaded and reproducible.

What it can bundle:

  • Your main wheel

  • Any number of additional wheels

  • All their dependencies (downloaded and stored locally)

  • Optional include files (configs, docs, whatever)

  • Pre-install and post-install scripts (shell, Python, etc.)

And it’s 100% reproducible, so that the archive installs the exact same versions every time, no network access needed.

Build tool integration:

If you’re using Poetry, Hatch, or PDM, I’ve released plugins for all three:

  • Just add the plugin to your pyproject.toml

  • Specify your build details (main wheel, includes, scripts, etc.)

  • Run your normal build command and you’ll get a .chub alongside your .whl

It’s one of the easiest ways to ship Python tools that just work, whether you’re distributing internally, packaging for air-gapped environments, or dropping into Docker builder stages.

Plugins repo: https://github.com/Steve973/pychub-build-plugins

Why not just use some other bundling/packaging tool?

Well, depending on your needs, maybe you should! I don’t think pychub replaces everything. It just solves a different problem.

If you want sealed apps with bundled runtimes, use PEX or PyOxidizer.
If you’re distributing scripts, zipapp is great.
But if you want a wheel-based, network-free, single-file installer that works on any Python 3.9+ environment, then pychub might be the right tool.

That’s it. I built it because I needed it to include plugins for a platform that I am building. If it helps you too, even better. I will be actively supporting this, and if you would like to take it for a spin and see if you like it, I’d be honored to hear your feedback. If you want a feature added, etc, please let me know.
Issues, suggestions, and PRs are all welcome.

Thanks for your time and interest!

Steve

9 Likes

Here are the pypi links:

https://pypi.org/project/pychub/
https://pypi.org/project/pychub-hatch-plugin/

I noticed that I didn’t update the “main” readme in the plugins repo, so that documentation is terrible, and you should avoid it. The short readme files under each plugin are much better (in the github repo). The same readme shows for each of the plugins on pypi.

https://pypi.org/project/pychub-pdm-plugin/
https://pypi.org/project/pychub-poetry-plugin/

Since I’m a newer user on here, I can only show 2 links per post, so these are the other two plugins.

Interesting! So if I understand correctly this is somewhat like zipapp, but supports extension modules and such as well?

1 Like

Zipapp is a bit different. If you take a look at the user guide, you can see a table of feature comparisons. It should answer all of your questions. But I can give you a brief overview.

If you build a wheel, pychub will take that, and all of its dependencies, and bundle it in a zip archive. You can add pre and post installation scripts, plus any other files that you want to include, and it will all be available on the target machine after you run the .chub file. And, also, you have plugins to integrate it with hatch, pdm, and poetry. If you have a chubproject.toml file, you can drop that content directly into your pyproject.toml file, and if you’ve enabled the plugin correctly, it’ll just work, and produce the .chub file right after the wheel is built. There are examples of this in the plugin readme files, too. Let me know if I can assist further and thank you for taking the time to reply to my post.

Here’s a direct link to the comparison table: pychub/USER_GUIDE.md at main · Steve973/pychub · GitHub

2 Likes

Also, if you think that it could fit in with anything CPython related, I’m open to ideas and collaboration.

Trying this out, it looks like for packages with compiled extensions (or dependencies with compiled extensions like e.g. numpy , pillow , or pydantic_core) the wheels for which ever combination of Python version, arch, OS you happen to be on are what get included. You probably need to add the full set of tags from wheels to the produced archives or add a check that fails if any wheels with language, abi, or platform tags set.

From a quick skim of the documentation I did not see this mentioned (maybe in a footnote on a compatibility table?), given the importance of supporting extensions modules to broad swaths of Python use cases, I think this limitation should be more clearly addressed.

6 Likes

Hi, and thank you for your feedback! I completely agree with you. This first release is a bit more basic than it will become, but I thought it was viable enough for an introductory release. This is exactly the type of feedback I was hoping for, and I appreciate that you took the time to comment.

Right now, the documentation does very briefly mention that cross-platform support is limited and that wheels “must be xplat,” but, as you wisely caught, that’s tucked away in a comparison table and not at all obvious. I’m planning a few things to address this, both in the near term and longer term.

First, I’ll make the limitation far more explicit in the docs. .chub files are only portable if all bundled wheels are universal, with things like py3-none-any, manylinux, or universal2. As soon as platform-specific wheels are involved, the bundle is no longer portable. I have created an issue to immediately address this: Improve documentation to call out the limited support for cross-platform features · Issue #5 · Steve973/pychub · GitHub

Next, I’m going to add build-time detection. If platform or ABI-specific wheels are included, pychub will warn or fail unless the user explicitly passes a --force flag. That should help prevent people from thinking they’ve built something portable when they haven’t. I have created a second issue for this: Add Build Time Platform Detection · Issue #6 · Steve973/pychub · GitHub

I’m also planning to modify the output filename when non-universal wheels are present. Instead of a plain name like mypkg-1.0.0.chub, the tool will append tag information like cp311-cp311-manylinux_x86_64, so it’s obvious from the filename what environment the bundle is for.

In addition, the .chubconfig will record those tags, so that running python mypkg.chub --info will show exactly which interpreter and platform it was built against.

Eventually, I’d like to support bundling multiple wheels per dependency, each with different tags, and let the runtime choose the correct one. That would make a .chub truly cross-platform, rather than tied to the build host. I’d also probably add a flag to allow selecting or preferring one platform over another when there are multiple options.

Again, I really appreciate you pointing this out. It’s valuable feedback, and I’ll use it to improve both the documentation and the tool itself. Please let me know if there’s anything else that I can do.

2 Likes

Thank you for the detailed comparisons to similar tools in the user guide! That must take some time to do, but it is very helpful. :slightly_smiling_face:

2 Likes

Hi, and thank you for taking the time to have a look and even reply! I am always glad to hear any feedback, and especially so when someone found something to be helpful. I showed the comparison because I didn’t want anybody to think that I was trying to compete with any of those tools, or replace them. If it helps you (or anyone else) find the right tool, and if it’s not even pychub, then that’s still great.

Thanks again, and let me know if you have any questions.

1 Like

If anyone is watching, I will be releasing 2.0.0 very soon. It will support multi-platform compatibility, path dependencies, and other improvements. I hope that a few people might find it more useful, and I always look forward to feedback of any kind.

1 Like