№ 02 · Writings · essay
A Node.js Developer's Journey into Python Territory
Navigating Python's ecosystem as a Node.js developer — package management, virtual environments, and the tools that bridge the gap.
- Published
- Read
- 2m
Contents
My first serious Python project as a Node.js developer was disorienting. The package management, the project structure, the development workflow — everything worked differently. Some of it was better. Some of it was frustrating. All of it was worth understanding.
The Cultural Shock: Package Management
Coming from npm's package.json and node_modules, Python's approach to dependencies took some adjustment.
# requirements.txt - Python's answer to package.json dependencies
flask==3.1.0
requests==2.32.3
SQLAlchemy==2.0.40What struck me immediately was the absence of a central configuration file that handled both dependencies and scripts. Instead, Python projects typically separate these concerns:
requirements.txtfor production dependenciesrequirements-dev.txtfor development toolsMakefileor scripts for automation
This separation offers flexibility but requires a mental shift when you're used to having everything defined in a single manifest file.
The Python Development Trinity: Black, Flake8, and MyPy
If ESLint and Prettier are the guardians of JavaScript code quality, Python has its own set of defenders:
Black: The Uncompromising Formatter
Black is Python's Prettier — it formats your code with minimal configuration options. That turned out to be exactly what I needed.
# Adding to requirements-dev.txt
black==25.1.0No more style debates. Black just works.
Flake8: The Linter
Flake8 combines multiple Python linting tools into one package. It identifies potential bugs, enforces style guides, and checks for code complexity.
# A typical .flake8 configuration
[flake8]
max-line-length = 88
extend-ignore = E203
exclude = .git,__pycache__,build,distMyPy: Type Checking Without TypeScript
MyPy is Python's static type checker. Coming from TypeScript, this was the tool I was most relieved to find:
def get_user(user_id: int) -> dict:
"""Retrieve user data from the database."""
return {"id": user_id, "name": "John Doe", "active": True}MyPy catches type-related bugs before runtime — familiar territory for TypeScript developers.
The Unsung Hero: Vulture
One tool I didn't initially appreciate was Vulture – a utility that finds unused code. In large JavaScript projects, tree-shaking often handles this automatically, but Python's dynamic nature makes dead code detection valuable:
# Find unused code
vulture my_project/Vulture has caught abandoned functions I would have maintained indefinitely.
Automation: The Makefile Renaissance
In JavaScript projects, npm scripts handle most automation tasks. Python developers, however, often reach for a much older tool: Make.
# Makefile
.PHONY: format lint test clean
format:
black src tests
lint:
flake8 src tests
mypy src
test:
pytest tests/
clean:
rm -rf __pycache__/ .pytest_cache/ .mypy_cache/A Makefile is a simple, language-agnostic command registry — useful when projects mix Python with other technologies.
Virtual Environments: The Node.js Dev's Confusion
The concept that took longest to appreciate was virtual environments. In Node.js, dependencies are project-scoped by default. Python requires explicit isolation:
# Creating and activating a virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activateIt felt like extra overhead until I hit dependency conflicts between projects. Now I see virtual environments as a more transparent version of what npm does behind the scenes.
Bringing It All Together: My Python Development Workflow
After months of exploration, I settled on a workflow that feels natural for a Node.js developer working in Python:
- Set up a virtual environment for each project
- Create separate requirements files for production and development
- Configure Black, Flake8, and MyPy for code quality
- Use a Makefile for common tasks
- Set up pre-commit hooks for automated checks
# A typical development setup
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt -r requirements-dev.txt
make format # Run Black
make lint # Run Flake8 and MyPyFinal Thoughts
The biggest lesson from crossing ecosystems: work with the language's approach instead of fighting it. Python's philosophy — explicit over implicit, one obvious way to do things — is different from Node.js, but the goal is the same: clean, maintainable code that solves real problems.
I initially tried to make Python feel like Node.js. The setup got better once I stopped.