1. Home
  2. Developer tools
  3. requirements.txt to pyproject.toml

requirements.txt to pyproject.toml

Move a Python project to pyproject.toml so modern tools such as uv, Poetry and Hatch can manage it, without retyping every dependency.

Free, no sign-up. Runs in your browser: nothing is uploaded.

How to use requirements.txt to pyproject.toml

  1. Paste requirements.txt (and optional dev requirements).
  2. Choose PEP 621 or Poetry and set the name and Python version.
  3. Copy or download pyproject.toml.

Features

  • PEP 508 parsing: extras, specifiers, markers and direct URLs
  • PEP 621 [project] dependencies with a PEP 735 dev group
  • Poetry tables with carets, extras and markers
  • Notes for -r includes, editable installs and nameless URLs
  • pyproject.toml back to requirements, Poetry carets expanded

Supported formats

You can open

  • TXT
  • TOML

You get

  • TOML
  • TXT

Private by design

Your files are opened and processed by your browser on this device. They are never uploaded to openWorkstand or anyone else, so the requirements.txt to pyproject.toml is safe for contracts, IDs, photos and work documents. After you have used it once while online, it also works without an internet connection. How local processing works

Good to know

  • Included files (-r), constraints (-c) and editable installs (-e) are reported, not followed.
  • Hashes are dropped; lockfiles handle them in pyproject-based tools.

Guide

Moving Python dependencies from requirements.txt to pyproject.toml

For years, Python projects listed their dependencies in requirements.txt and their metadata in setup.py. Today pyproject.toml holds both, and modern tools such as uv, Poetry, Hatch and PDM expect it. Converting by hand means retyping every line and getting extras and markers right. This converter reads a requirements file and writes the pyproject sections for it, and can turn a pyproject back into requirements for tools that still need one.

What a requirement line contains

Each line follows PEP 508. It starts with a package name, optionally followed by extras in square brackets, version specifiers and an environment marker after a semicolon: pywin32==306 ; sys_platform == "win32" installs that package only on Windows. Version specifiers come from PEP 440: == pins, >= and < set bounds, and ~= is the compatible-release operator. A direct reference looks like mypkg @ https://example.com/mypkg-1.0.tar.gz.

The PEP 621 format

The default output is the standard [project] table used by uv, pip and most build backends. Every requirement becomes a string in the dependencies array, exactly as PEP 508 writes it, with double quotes inside markers changed to single quotes so the TOML string stays valid. The table also gets name, version and requires-python, and a minimal [build-system] using hatchling so pip install . works.

Development dependencies

Test and lint tools belong in a separate group so production installs stay small. Paste them into the development box and they appear under [dependency-groups] as a dev list, the format defined by PEP 735, which uv and pip understand. In Poetry mode they go into Poetry’s own group table instead.

The Poetry format

Poetry keeps dependencies in [tool.poetry.dependencies] as a table. A plain version becomes name = "2.32.3", ranges are carried over, and a requirement with extras or markers becomes an inline table such as requests = { version = "2.32.3", extras = ["socks"] }. The Python requirement is written as a caret, so >=3.11 becomes ^3.11.

Lines that are not converted

Some lines in requirements files are instructions for pip rather than requirements. -r other.txt includes another file, -c adds constraints, --index-url changes the package index and -e installs a local project in editable mode. A Git or URL line without a package name cannot become a named dependency either. Each of these is listed in a note so nothing disappears silently, and hashes from --hash are dropped because pyproject-based tools keep hashes in their lockfiles.

A worked example

The Sample requirements file has nine lines. The output’s dependencies array contains six entries, including "Django>=4.2,<5.0", "psycopg[binary]>=3.1", "celery~=5.4" and "pywin32==306; sys_platform == 'win32'". Two notes explain the skipped lines: the -r requirements-dev.txt include, and the Git URL that has no package name. Switching to Poetry rewrites the same dependencies as [tool.poetry.dependencies].

The reverse direction

Choose “pyproject.toml → requirements.txt” and paste a pyproject file. PEP 621 dependency strings are written out as they are; Poetry entries are converted, with a caret like ^4.2 expanded to >=4.2,<5, and * written as the bare name. This is useful for Docker builds, deployment platforms and scanners that only read requirements files.

Checked against the current version of the requirements.txt to pyproject.toml on .

Troubleshooting

The file does not open

Check that it is one of the supported formats above and opens in another app. Damaged files and password-protected PDFs cannot be read until they are repaired or unlocked.

It is slow or stops on a very large file

Everything runs on your device, so speed depends on its memory. Close other tabs, use a computer rather than a phone, or split the file into smaller parts first.

The download did not start

Look for your browser’s download bar or icon. Some browsers ask once before a site may download files; allow it and click the button again.

Frequently asked questions

How do I install from the new pyproject.toml?

With uv, run uv sync, which creates a virtual environment and a uv.lock. With pip, run pip install -e . inside a virtual environment. With Poetry, run poetry install. Each tool reads the same dependency list but writes its own lockfile.

What does ~=5.4 mean?

It is the compatible release operator from PEP 440: ~=5.4 means >=5.4 and ==5.*, so 5.9 is allowed but 6.0 is not. ~=5.4.1 is stricter and allows only 5.4.x releases from 5.4.1 up.

Should the pyproject pin exact versions like requirements.txt?

Usually not. pyproject lists the ranges your code supports; exact pins belong in a lockfile (uv.lock, poetry.lock). Keep == only where a newer version is known to break.

Where did my -r dev.txt line go?

Included files are not followed, because the tool only sees the text you pasted. Paste the dev requirements into the development box and they become a dependency group.

Keep working with the result

After you download, choose “Save to Workstand” to keep the result in a folder on your computer, attach it to a project and create a follow-up task. It is saved by your browser, not uploaded.