HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
linkedin
shiv
Python2018–2025
linkedin / shiv

shiv

shiv is a command line utility for building fully self contained Python zipapps as outlined in PEP 441, but with all their dependencies included.

8Distinct people
11Mentions
0Explicit recommenders
2KGitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

shiv is a command line utility for building fully self contained Python zipapps as outlined in PEP 441, but with all their dependencies included.

GitHub

Where it is used

No documented product use has been verified yet.

What people are saying

No recommendation phrase was found in the indexed comments.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

Mentioned in the same Hacker News threads. That is not proof they are substitutes.

This week on Hacker News

Nov 7–Nov 14 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/14/2026, 1:49:46 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year11 dated mentions

Observed mentions: 2018-04-30 16:37:04 UTC to 2025-03-28 09:14:04 UTC.

01232018-01-01 00:00:00 UTC to 2019-01-01 00:00:00 UTC (exclusive): 1 mentions; 1 submissions, 0 comments20182019-01-01 00:00:00 UTC to 2020-01-01 00:00:00 UTC (exclusive): 3 mentions; 0 submissions, 3 comments2020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments20212022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 3 mentions; 0 submissions, 3 comments2024-01-01 00:00:00 UTC to 2025-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2025-01-01 00:00:00 UTC to 2026-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2025

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20182018-01-01 00:00:00 UTC2019-01-01 00:00:00 UTC110
20192019-01-01 00:00:00 UTC2020-01-01 00:00:00 UTC303
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC101
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC000
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC101
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC303
20242024-01-01 00:00:00 UTC2025-01-01 00:00:00 UTC101
20252025-01-01 00:00:00 UTC2026-01-01 00:00:00 UTC101

What Hacker News says

11 sources
My general solution to project management problems with PEP 723 scripts is to develop the script as a regular Python application that has `pyproject.toml`. It lets you use all of your normal tooling. While I don't use an LSP-based editor, it makes things easy with Ruff and Pyright. I run my standard Poe the Poet (https://poethepoet.natn.io/) tasks for formatting, linting, and type checking as in any other project. One drawback of this workflow is that by default, you duplicate the dependencies: you have them both in the PEP 723 script itself and `pyproject.toml`. I just switched a small server application from shiv (https://github.com/linkedin/shiv) to inline script metadata after a binary dependency broke the zipapp. I experimented with having `pyproject.toml` as the single source of truth for metadata in this project. I wrote the follow
Read the rest
ing code to embed the metadata in the script before it was deployed on the server. In a project that didn't already have a build and deploy step, you'd probably want to modify the PEP 723 script in place. #! /usr/bin/env python3 # License: https://dbohdan.mit-license.org/@2025/license.txt import re import tomllib from pathlib import Path from string import Template import tomli_w DEPENDENCIES = "dependencies" PROJECT = "project" REQUIRES_PYTHON = "requires-python" DST = Path("bundle.py") PYPROJECT = Path("pyproject.toml") SRC = Path("main.py") BUNDLE = Template( """ #! /usr/bin/env -S uv run --quiet --script # /// script $toml # /// $code """.strip() ) def main() -> None: with PYPROJECT.open("rb") as f: pyproject = tomllib.load(f) toml = tomli_w.dumps( { DEPENDENCIES: pyproject[PROJECT][DEPENDENCIES], REQUIRES_PYTHON: pyproject[PROJECT][REQUIRES_PYTHON], }, indent=2, ) code = SRC.read_text() code = re.sub(r"^#![^\n]+\n", "", code) bundle = BUNDLE.substitute( toml="\n".join(f"# {line}" for line in toml.splitlines()), code=code, ) DST.write_text(bundle) if __name__ == "__main__": main()
In Using uv and PEP 723 for Self-Contained Python Scripts
All right, let me tell you the history of recur to explain this choice. :-) I wrote the initial version in Python in 2023 and used simpleeval [1] for the condition expressions. The readme for simpleeval states: > I've done the best I can with this library - but there's no warranty, no guarantee, nada. A lot of very clever people think the whole idea of trying to sandbox CPython is impossible. Read the code yourself, and use it at your own risk. In early 2024, simpleeval had a vulnerability report that drove the point home [2]. I wanted to switch to a safer expression library in the rare event someone passed untrusted arguments to `--condition` and as a matter of craft. (I like simpleeval, but I think it should be used for expressions in trusted or semi-trusted environments.) First, I evaluated cel-python [3]. I didn't adopt it over the bi
Read the rest
nary dependency on PyYAML and concerns about maturity. I also wished to avoid drastically changing the condition language. Next in line was python-starlark-go [4], which I had only used in a project that ultimately didn't need complex config. I had been interested in Starlark for a while. It was an attractive alternative to conventional software configuration. I saw an opportunity to really try it. A switch to python-starlark-go would have made platform-independent zipapps I built with shiv [5] no longer an option. This was when I realized I might as well port recur to Go, use starlark-go natively, and get static binaries out of it. I could have gone with cel-go, but like I said, I was interested in Starlark and wanted to keep expressions similar to how they were with simpleeval. [1] https://github.com/danthedeckie/simpleeval [2] https://github.com/danthedeckie/simpleeval/issues/138 [3] https://github.com/cloud-custodian/cel-python [4] https://github.com/caketop/python-starlark-go [5] https://github.com/linkedin/shiv#gotchas
In Show HN: Retry a command with exponential backoff and jitter (+ Starlark exprs)
Python has zipapps (https://peps.python.org/pep-0441/), which are standardized and similar to JARs. You can build a zipapp that includes your application's dependencies using a tool like shiv or PEX, only with binary extensions the artifacts are still per-platform: https://github.com/linkedin/shiv#gotchas. I recommend users to install my Python programs with pipx (https://github.com/pypa/pipx). I think it is the best option when the audience is at all technical. pipx makes such a big difference for managing Python applications. It avoids the version conflicts of `pip install --user` and the pain of manually creating per-application venvs. In general, it provides a reasonable user experience. Because of this user-friendliness, I can recommend pipx as the primary installation method and expect people to succeed at installing the program wit
Read the rest
h it. (I don't see issues about pipx installation in the trackers of projects that recommend it.) My programs have binary dependencies but no GUI.
In PysimpleGUI
> Can you install any script from arbitrary urls using pip? You don't need to. Download any module or packgage, put it next to your code, and you can import it. There is nothing to do. There is not even need for metadata. But yes, pip can install packages from arbitrary URLS, including git repos, if they contains the right metadata. What's more, with something like shiv (https://github.com/linkedin/shiv), you can actually bundle those dependancies into one zipapp (an official python feature, see https://docs.python.org/fr/3/library/zipapp.html), which is basically a zip containing your entire project that you can just execute like if it were one py file.
In Deno Is a Browser for Code
> I agree, but if you for instance look at the TypeScript comparison sub-thread, you'll see that all the issues with both the syntax and implementation of the type-system are being aggressively resolved, and likely will all be so by 3.9. I'm happy to hear that; hopefully the efforts really do address these issues well. > I find poetry a joy to use. If you want to bypass venvs all together, there's a lot of work to make that a reality, such as https://github.com/David-OConnor/pyflow. I'll have to check those out, but one inherent problem is that even if these tools really do solve my pain points, adopting them means I'm leaving my org on a relatively small island, isolated from the Python community. If these really are the holy grail, why isn't the broader Python community adopting them? Please don't take this as me looking for something w
Read the rest
rong--whatever Python build tool I use, I'll eventually need support and there's a lot to be said for having a thriving community that has almost always run into my exact problem before. > Python in 3.5 added complete zip app support, which has improved this dramatically from my perspective. Extended by things like shiv https://github.com/linkedin/shiv make it fairly complete. We're currently using this via pex. It mostly works, but we still run into problems occassionally (system dependencies, for example). Figuring out how to integrate these tools into the broader build process is another problem to solve--we're using `pants` which supports pex out of the box, but we're running into lots of bugs or other problems. I'll keep an eye on shiv. > This is interesting to me. I prefer async/await in general, because it has become a standard across programming languages and I find it really easy to reason about. I also find channels to be too widely seen as a cure-all, when the only study so far has shown they actually led to an increase bug count. But I don't discount the value of real-parallelism, and am glad to see that Python has been pushing harder on that lately, with things like subshells that allow bypassing the GIL on a single thread. My biggest issues with async/await are (1) every package needs an async variant (async boto, async docker, etc etc). We work around this by running them in a thread pool executor, and I think that works, but I don't know if I'm holding the GIL unnecessarily and causing performance issues (fundamentally difficult to diagnose). This is roughly the "what color is my function" problem. (2) it's really easy to starve the event loop by calling into something that transitively makes a sync call or otherwise just does a lot of CPU-heavy work. We've run into both kinds in production and they've been really hard to troubleshoot (because the requests that time out often aren't the ones that are actually causing the problems). (3) dynamic typing means it's super easy to forget to await things. Tests should catch this, but we find ourselves writing tests _just_ to catch this (e.g., we now write tests for entrypoints that _just_ `await lib_function(params)`; we would normally not write tests for such simple functions, but now we have to). Static typing is the right way to solve this and mypy does, but mypy has too many other issues (at the moment) for our org. One substantial criticism of goroutines is that they're less safe than async/await because you need to make sure the code you're running is threadsafe. I appreciate this criticism, but I think it's the right tradeoff for Go's performance aspirations (another great high-performance alternative is Rust's borrow checker, but that's the wrong tradeoff for Go's developer productivity aspirations).
In Python at Scale: Strict Modules
> type-system I agree, but if you for instance look at the TypeScript comparison sub-thread, you'll see that all the issues with both the syntax and implementation of the type-system are being aggressively resolved, and likely will all be so by 3.9. > Good way to constrain the dynamism so performance could be improved Couldn't agree more! > environment I find poetry a joy to use. If you want to bypass venvs all together, there's a lot of work to make that a reality, such as https://github.com/David-OConnor/pyflow. > packaging Python in 3.5 added complete zip app support, which has improved this dramatically from my perspective. Extended by things like shiv https://github.com/linkedin/shiv make it fairly complete. > async/await This is interesting to me. I prefer async/await in general, because it has become a standard across programming l
Read the rest
anguages and I find it really easy to reason about. I also find channels to be too widely seen as a cure-all, when the only study so far has shown they actually led to an increase bug count. But I don't discount the value of real-parallelism, and am glad to see that Python has been pushing harder on that lately, with things like subshells that allow bypassing the GIL on a single thread.
In Python at Scale: Strict Modules

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.