Learn how to build and publish a Python package to PyPI, from project structure and pyproject.toml to building, testing, and publishing your package.
Updated August 2026 — full tutorial restored for this URL.
TL;DR
-
Python packages are typically published to PyPI, while JavaScript and TypeScript packages are published to npm.
-
Use a clean
srcproject layout withpyproject.tomlto define your package metadata, dependencies, and build system. -
Build your package into distributable
.whland.tar.gzartifacts before publishing. -
Test on TestPyPI first to verify that your package can be installed and works as expected.
-
If you also provide a JavaScript SDK, publish it separately to npm and manage its versioning independently from the Python package.
The URL slug says Python SDK … to npm. Clarification up front:
- Python libraries publish to PyPI (
pip install …). - npm is for JavaScript/TypeScript packages. You only publish to npm if you also ship a JS client SDK.
This tutorial focuses on a proper Python package on PyPI, then notes the npm path for a companion JS SDK.
1. Project layout
my_sdk/
pyproject.toml
README.md
src/my_sdk/__init__.py
src/my_sdk/client.py
tests/test_client.py
2. pyproject.toml
[build-system]
requires = ["setuptools>=61", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "my-sdk"
version = "0.1.0"
description = "Example Python SDK"
readme = "README.md"
requires-python = ">=3.9"
dependencies = ["requests>=2.31"]
[tool.setuptools.packages.find]
where = ["src"]
3. Build artifacts
python -m pip install build twine
python -m build
# creates dist/*.whl and dist/*.tar.gz
4. Publish to PyPI (or TestPyPI)
# Test first
python -m twine upload --repository testpypi dist/*
pip install -i https://test.pypi.org/simple/ my-sdk==0.1.0
# Production
python -m twine upload dist/*
Use API tokens from pypi.org — never commit passwords.
5. Optional: JS SDK on npm
If your product needs a browser/Node client, create a separate packages/js-sdk with package.json, build with tsc, then:
npm login
npm publish --access public
Keep Python (PyPI) and JS (npm) versioned independently; document both in the monorepo README.
Final Thoughts
Publishing a Python package is more straightforward when you treat packaging and distribution as part of the project from the beginning. A clean structure, a properly configured pyproject.toml, and a repeatable build process give users a reliable package they can install and use.
For Python libraries, PyPI is the natural distribution channel. npm only becomes relevant when your product also includes a JavaScript or TypeScript SDK, in which case the two packages should be maintained and versioned independently.
Before publishing to production, test your package through TestPyPI, verify the installation, and protect your publishing credentials with API tokens. These simple steps can prevent avoidable release problems as your package grows.