https://github.com/duriantaco/fyn
Fyn is a fork of uv for fast Python package management, dependency resolution, virtual environments, and pyproject.toml workflows.
https://github.com/duriantaco/fyn
dependency-management fork forked-repo package-manager packaging pyproject-toml python resolver uv
Last synced: 6 days ago
JSON representation
Fyn is a fork of uv for fast Python package management, dependency resolution, virtual environments, and pyproject.toml workflows.
- Host: GitHub
- URL: https://github.com/duriantaco/fyn
- Owner: duriantaco
- License: apache-2.0
- Created: 2026-03-23T09:29:33.000Z (about 1 month ago)
- Default Branch: main
- Last Pushed: 2026-04-16T13:34:12.000Z (11 days ago)
- Last Synced: 2026-04-16T14:25:08.548Z (11 days ago)
- Topics: dependency-management, fork, forked-repo, package-manager, packaging, pyproject-toml, python, resolver, uv
- Language: Rust
- Homepage: https://duriantaco.github.io/fyn/
- Size: 78.5 MB
- Stars: 304
- Watchers: 3
- Forks: 4
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE-APACHE
- Security: SECURITY.md
Awesome Lists containing this project
- awesome - duriantaco/fyn - Fyn is a fork of uv for fast Python package management, dependency resolution, virtual environments, and pyproject.toml workflows. (Rust)
README
# fyn
An extremely fast Python package and project manager, written in Rust.
**fyn** is an independent community fork of [uv](https://github.com/astral-sh/uv). It started on
uv's foundation, but it now has its own commands, settings, defaults, and behavior, alongside
reduced package-index request metadata, added features, and long-standing bug fixes. See
[MANIFESTO.md](https://github.com/duriantaco/fyn/blob/main/MANIFESTO.md) for the full story.
## Highlights
- A single tool to replace `pip`, `pip-tools`, `pipx`, `poetry`, `pyenv`, `twine`, `virtualenv`, and
more.
- 10-100x faster than `pip`.
- Provides [comprehensive project management](#projects), with a universal lockfile.
- Built-in [task runner](#task-runner) — define and run project tasks in `pyproject.toml`.
- [Activates virtual environments](#shell-activation) with `fyn shell`.
- [Upgrades dependencies](#upgrade-dependencies) in one command with `fyn upgrade`.
- [Runs scripts](#scripts), with support for inline dependency metadata.
- [Installs and manages](#python-versions) Python versions.
- [Runs and installs](#tools) tools published as Python packages.
- Includes a [pip-compatible interface](#the-pip-interface) for a performance boost with a familiar
CLI.
- Supports Cargo-style workspaces for scalable projects.
- Disk-space efficient, with a global cache for dependency deduplication.
- Reduced package-index request metadata — compared with upstream uv, fyn sends a minimal
`fyn/` `User-Agent` header to package indexes such as PyPI, instead of `uv/`
plus the extra LineHaul environment metadata uv included. This reduces what is exposed in that
header, but package indexes still receive normal network and request information.
- Supports macOS, Linux, and Windows.
## Installation
From [PyPI](https://pypi.org/project/fyn/):
```bash
# With pip.
pip install fyn
```
```bash
# Or pipx.
pipx install fyn
```
Or build from source:
```bash
cargo install --path crates/fyn
```
See the command line reference with `fyn help`.
## Documentation
The live docs site is [duriantaco.github.io/fyn](https://duriantaco.github.io/fyn/). The source of
truth still lives in [`docs/`](https://github.com/duriantaco/fyn/tree/main/docs) in the repository.
Start here:
- [Documentation home](https://duriantaco.github.io/fyn/)
- [Getting started](https://duriantaco.github.io/fyn/getting-started/first-steps/)
- [Working on projects](https://duriantaco.github.io/fyn/guides/projects/)
- [Running scripts](https://duriantaco.github.io/fyn/guides/scripts/)
- [Command reference](https://duriantaco.github.io/fyn/reference/cli/)
For CLI-specific help, use `fyn help` or `fyn help `.
## Features
### Projects
fyn manages project dependencies and environments, with support for lockfiles, workspaces, and more,
similar to `rye` or `poetry`:
```console
$ fyn init example
Initialized project `example` at `/home/user/example`
$ cd example
$ fyn add ruff
Creating virtual environment at: .venv
Resolved 2 packages in 170ms
Installed 2 packages in 1ms
+ ruff==0.5.0
$ fyn run ruff check
All checks passed!
$ fyn lock
Resolved 2 packages in 0.33ms
$ fyn sync
Resolved 2 packages in 0.70ms
Checked 1 package in 0.02ms
```
### Task runner
Define tasks in your `pyproject.toml` and run them with `fyn run`:
```toml
[tool.fyn.tasks]
test = { cmd = "pytest -xvs", env = { PYTHONWARNINGS = "error" } }
lint = "ruff check ."
format = { cmd = "ruff format .", description = "Format code" }
check = { chain = ["lint", "test"], description = "Lint then test" }
```
```console
$ fyn run test
# runs pytest -xvs
$ fyn run check
# runs lint, then test
$ fyn run test -- -k mytest
# extra args are passed through
$ fyn run --list-tasks
Available tasks:
check Lint then test
format Format code
lint ruff check .
test pytest -xvs
```
Task `env` values are applied to the spawned command. For chained tasks, parent `env` values are
inherited by child tasks, and child task values take precedence. Extra arguments are supported for
`cmd` tasks, but not for chained tasks.
### Shell activation
Activate the project's virtual environment in a new shell:
```console
$ fyn shell
success: Activated virtual environment at .venv
Type exit to deactivate.
```
Works with bash, zsh, fish, nushell, powershell, and cmd.
If you pass a path, `fyn shell` activates that environment directly. Otherwise it uses `VIRTUAL_ENV`
when set, then the discovered project environment, then a local `.venv`. Use `--no-project` to skip
project discovery and only check the current directory.
### Upgrade dependencies
Upgrade all or specific dependencies in one command:
```console
$ fyn upgrade
info: Upgrading all dependencies...
success: Dependencies upgraded successfully.
$ fyn upgrade requests flask
info: Upgrading: requests, flask
success: Dependencies upgraded successfully.
```
Supports `--dry-run` and `--no-sync`.
`fyn upgrade` is the convenience form of running `fyn lock --upgrade` and then `fyn sync`.
### Project status
Inspect the current project and environment state:
```console
$ fyn status
current directory: /home/user/example
project directory: /home/user/example
managed project: yes
workspace root: /home/user/example
pyproject.toml: yes
fyn.lock: yes
pip-in-project: warn
environment: /home/user/example/.venv
python: /home/user/example/.venv/bin/python3 (3.12.0)
```
Use `--check` to fail when obvious project checks do not pass, or `--json` for scripting and editor
integrations.
### PyTorch backend diagnosis
Inspect the current machine and environment before installing or reinstalling PyTorch:
```console
$ fyn torch doctor
PyTorch doctor
recommended backend: cu130
next command:
fyn pip install torch torchvision torchaudio --torch-backend=cu130
```
Use `--json` for scripting. `fyn torch doctor` reports the recommendation and current package state,
but does not modify `pyproject.toml`.
### Scripts
fyn manages dependencies and environments for single-file scripts.
Create a new script and add inline metadata declaring its dependencies:
```console
$ echo 'import requests; print(requests.get("https://example.com"))' > example.py
$ fyn add --script example.py requests
Updated `example.py`
```
Then, run the script in an isolated virtual environment:
```console
$ fyn run example.py
Reading inline script metadata from: example.py
Installed 5 packages in 12ms
```
### Tools
fyn executes and installs command-line tools provided by Python packages, similar to `pipx`.
Run a tool in an ephemeral environment using `fynx` (an alias for `fyn tool run`):
```console
$ fynx pycowsay 'hello world!'
Resolved 1 package in 167ms
Installed 1 package in 9ms
"""
------------
< hello world! >
------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
```
Install a tool with `fyn tool install`:
```console
$ fyn tool install ruff
Resolved 1 package in 6ms
Installed 1 package in 2ms
+ ruff==0.5.0
Installed 1 executable: ruff
$ ruff --version
ruff 0.5.0
```
### Python versions
fyn installs Python and allows quickly switching between versions.
Install multiple Python versions:
```console
$ fyn python install 3.12 3.13 3.14
Installed 3 versions in 972ms
+ cpython-3.12.12-macos-aarch64-none
+ cpython-3.13.9-macos-aarch64-none
+ cpython-3.14.0-macos-aarch64-none
```
Use a specific Python version in the current directory:
```console
$ fyn python pin 3.11
Pinned `.python-version` to `3.11`
```
### The pip interface
fyn provides a fast, pip-compatible interface for common `pip`, `pip-tools`, and `virtualenv`
workflows.
For many common workflows, you can switch to the `fyn pip` interface with minimal changes and keep
the same overall workflow shape, while getting a 10-100x speedup.
Compile requirements into a platform-independent requirements file:
```console
$ fyn pip compile requirements.in \
--universal \
--output-file requirements.txt
Resolved 43 packages in 12ms
```
Create a virtual environment:
```console
$ fyn venv
Using Python 3.12.3
Creating virtual environment at: .venv
Activate with: source .venv/bin/activate
```
Install the locked requirements:
```console
$ fyn pip sync requirements.txt
Resolved 43 packages in 11ms
Installed 43 packages in 208ms
+ babel==2.15.0
+ certifi==2024.7.4
...
```
### Cache size limit
Keep your cache from growing unbounded:
```bash
export UV_CACHE_MAX_SIZE=2G
```
Oldest entries are automatically pruned after every command when the cache exceeds the limit.
Supports `K`, `M`, `G`, and `T` suffixes.
### Custom lockfile name
Use different lockfiles for different environments:
```bash
UV_LOCKFILE=linux.lock fyn lock
UV_LOCKFILE=macos.lock fyn lock
```
### Private index support
Environment variables work in index URLs — useful for private indexes with credentials:
```toml
[[tool.fyn.index]]
name = "private"
url = "https://${PYPI_TOKEN}@pypi.example.com/simple/"
```
Explicit indexes are also respected for transitive dependencies, so you don't have to list every
internal package as a direct dependency.
## Migrating from uv
fyn is close to uv, but not a zero-edit rename. Most command-line workflows and `UV_*` environment
variables carry over, but project metadata and lockfile names differ.
```bash
# 1. Rename your lockfile
mv uv.lock fyn.lock
# 2. In pyproject.toml, rename [tool.uv] to [tool.fyn]
sed -i 's/\[tool\.uv\]/[tool.fyn]/' pyproject.toml
# 3. Use fyn instead of uv
fyn sync
fyn run pytest
fynx ruff check .
```
## Contributing
We are passionate about supporting contributors of all levels of experience and would love to see
you get involved in the project. See the
[contributing guide](https://github.com/duriantaco/fyn/blob/main/CONTRIBUTING.md) to get started.
## FAQ
#### What platforms does fyn support?
The same ones as uv: macOS, Linux, and Windows, across x86_64 and aarch64.
#### Is fyn compatible with uv?
At the workflow level, often yes, but not as a drop-in replacement. Many commands and `UV_*`
environment variables carry over, but fyn now has fork-specific commands, config, defaults, and
behavior. Projects still need `[tool.uv]` renamed to `[tool.fyn]` and `uv.lock` renamed to
`fyn.lock` unless you override the lockfile name.
#### What's different from uv?
See [MANIFESTO.md](https://github.com/duriantaco/fyn/blob/main/MANIFESTO.md) for the fuller
comparison, or the table below for some of the larger user-visible differences:
| Area | uv | fyn |
| ----------------------------- | ------------------------------------- | --------------------------------------------- |
| Config namespace and lockfile | `[tool.uv]`, `uv.lock` | `[tool.fyn]`, `fyn.lock` |
| Package index User-Agent | `uv/` plus LineHaul metadata | Minimal `fyn/` |
| Task runner | No `[tool.uv.tasks]` | `[tool.fyn.tasks]` |
| `shell` command | No `uv shell` | `fyn shell` |
| `upgrade` command | No `uv upgrade` | `fyn upgrade` |
| `status` command | No `uv status` | `fyn status` |
| `torch doctor` command | No `uv torch doctor` | `fyn torch doctor` |
| Managed-project `pip` policy | No `pip-in-project` setting | `pip-in-project`: `warn`, `error`, or `allow` |
| Cache size limit | No `UV_CACHE_MAX_SIZE` | `UV_CACHE_MAX_SIZE` |
| Custom lockfile name | No `UV_LOCKFILE` | `UV_LOCKFILE` |
## Acknowledgements
fyn's dependency resolver uses [PubGrub](https://github.com/pubgrub-rs/pubgrub) under the hood.
We're grateful to the PubGrub maintainers, especially [Jacob Finkelman](https://github.com/Eh2406),
for their support.
fyn started as a fork of [uv](https://github.com/astral-sh/uv) by Astral and still shares
substantial ancestry with it.
Some of fyn's workflow UX, especially around task-running and future workflow ergonomics, has also
been informed by [Hatch](https://github.com/pypa/hatch).
fyn's Git implementation is based on [Cargo](https://github.com/rust-lang/cargo).
Some of fyn's optimizations are inspired by the great work we've seen in [pnpm](https://pnpm.io/),
[Orogene](https://github.com/orogene/orogene), and [Bun](https://github.com/oven-sh/bun). We've also
learned a lot from Nathaniel J. Smith's [Posy](https://github.com/njsmith/posy) and adapted its
trampoline for Windows support.
## License
fyn is licensed under either of
- Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
)
- MIT license ([LICENSE-MIT](LICENSE-MIT) or )
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in fyn
by you, as defined in the Apache-2.0 license, shall be dually licensed as above, without any
additional terms or conditions.