Skip to lesson
Python for JS Developers

Modules & ErrorsLesson 1 of 3

The Import System

4 min

Python's import system is simpler than JS modules in some ways and more structured in others. Every .py file is a module, and a directory of modules is a package. There is no node_modules folder: third-party packages are installed into a virtual environment (a .venv folder per project), and you declare dependencies in pyproject.toml (the modern standard) or a requirements.txt file.

The syntax maps cleanly. 'import { X } from "y"' becomes 'from y import X'. The as rename works the same way. There is no default export: you either import the module itself (import json) or names from it (from json import loads). The other big difference is Python's standard library: json, csv, re (regex), sqlite3, datetime, pathlib, http, and much more are built in. Many things that need npm install in JS need no installation at all.

Packages and __init__.py: a regular package is a directory containing an __init__.py file (often empty). The file runs when the package is first imported, so it can also re-export names, a bit like an index.js. Since Python 3.3, a directory without __init__.py can still be imported as a 'namespace package', but tools and test runners behave more predictably with regular packages, so include __init__.py in your own packages.

Modern type hints need fewer imports than older tutorials suggest. Since Python 3.9 you write list[str] and dict[str, int] with the built-in types, and since 3.10 you write str | None instead of Optional[str]. You will still see 'from typing import List, Optional' in older code; it works, but new code does not need it.

PEP 8 (Python's style guide) defines the import order: standard library first, then third-party packages, then your own local modules, with a blank line between each group. Tools like ruff and isort sort them for you automatically.

Quick reference

JavaScriptPythonNote
import { join } from "path"from os.path import joinKeyword order reversed
import * as fs from "fs"import osImport the whole module
import { x as y }from m import x as ySame rename idea
export defaultNo default exportsImport the module or its names
npm install / yarn addpip install (inside a venv)Package installer
package.jsonpyproject.toml / requirements.txtDependency file
node_modules/.venv/Per-project environment
index.js in a folder__init__.pyRuns when the package is imported

Side by side

JavaScript
// JavaScript Modules
import { useState } from "react";
import React from "react";
import { useState as uState } from "react";
import * as path from "path";
const fs = require("fs");
// npm install / package.json / node_modules
Python
# Python Imports
# 1. Standard library
import json
import os
from collections import Counter
from pathlib import Path

# 2. Third-party (pip install requests numpy)
import numpy as np        # rename
import requests

# 3. Local modules (your own files)
from myapp.utils import slugify

# Modern type hints: no typing import needed
def load(paths: list[str]) -> dict[str, int] | None:
    ...

Exercise

Real Python, running in your browser

Organize these imports in PEP 8 order:

Needed: 1. json and os (standard library) 2. datetime from datetime (standard library) 3. Counter from collections (standard library) 4. requests (third party) 5. calculate_tax from the local helpers.py file PEP 8: stdlib -> third-party -> local (blank line between groups)

Ctrl + Enter runCtrl + Shift + Enter checkTab indentEsc then Tab to leave the editorCtrl + / comment