A file that lists all the dependencies required by your project. It allows others to replicate your environment easily.
π§ Create One:
pip freeze > requirements.txtπ§ Install from It:
pip install -r requirements.txtπ‘ Real-life Use:
Sharing your project with teammates
Deploying to cloud services (e.g., Heroku, AWS, etc.)
Automating environments for CI/CD pipelines
<div class="infographic-pyfreeze">
<style>
.infographic-pyfreeze {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--mono-font: 'IBM Plex Mono', 'SFMono-Regular', Menlo, monospace;
--display-font: 'Fraunces', Georgia, serif;
--body-font: 'Inter', system-ui, sans-serif;
box-sizing: border-box;
max-width: 620px;
margin: 0 auto;
font-family: var(--body-font);
color: var(--ink);
background: var(--paper);
}
.infographic-pyfreeze[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
}
.infographic-pyfreeze *, .infographic-pyfreeze *::before, .infographic-pyfreeze *::after { box-sizing: border-box; }
.infographic-pyfreeze .fr-wrap { padding: 0 clamp(1rem, 4vw, 2rem) 1.5rem; }
.infographic-pyfreeze h1 {
font-family: var(--display-font); font-weight: 600;
font-size: clamp(1.35rem, 4.5vw, 1.8rem); text-align: center; margin: 1.5rem 0 0.25rem; letter-spacing: -0.01em;
font-family: var(--mono-font);
}
.infographic-pyfreeze .fr-sub { text-align: center; color: var(--ink-soft); font-size: 0.86rem; margin: 0 0 1.4rem; }
.infographic-pyfreeze .scenario {
text-align: center; font-size: 0.85rem; color: var(--ink-soft); margin-bottom: 1.1rem; line-height: 1.5;
}
.infographic-pyfreeze .scenario strong { color: var(--ink); }
.infographic-pyfreeze .env-card {
border: 1.5px solid var(--line); border-radius: 8px; overflow: hidden; margin-bottom: 1.1rem;
}
.infographic-pyfreeze .env-bar {
font-family: var(--mono-font); font-size: 0.75rem; font-weight: 700; color: var(--ink-soft);
background: var(--paper-alt); padding: 0.4rem 0.7rem; border-bottom: 1px solid var(--line);
}
.infographic-pyfreeze .chip-row { display: flex; flex-wrap: wrap; gap: 0.4rem; padding: 0.7rem; justify-content: center; }
.infographic-pyfreeze .chip {
font-family: var(--mono-font); font-size: 0.78rem; font-weight: 700;
background: var(--accent-soft); border: 1.5px solid var(--accent); color: var(--accent);
padding: 0.3rem 0.6rem; border-radius: 999px;
}
.infographic-pyfreeze .chip .ver { opacity: 0.7; font-weight: 400; }
.infographic-pyfreeze .run-row { display: flex; justify-content: center; margin-bottom: 1.1rem; }
.infographic-pyfreeze .run-btn {
font: inherit; font-family: var(--mono-font); font-size: 0.85rem; font-weight: 700;
background: var(--accent); color: #fff; border: none; border-radius: 999px;
padding: 0.55rem 1.2rem; cursor: pointer;
}
.infographic-pyfreeze .run-btn:disabled { opacity: 0.5; cursor: default; }
.infographic-pyfreeze .arrow-down { text-align: center; color: var(--accent); font-size: 1.2rem; margin-bottom: 0.9rem; }
.infographic-pyfreeze .req-file {
font-family: var(--mono-font); font-size: 0.82rem; background: var(--paper-alt); border: 1.5px solid var(--line);
border-radius: 8px; overflow: hidden; margin-bottom: 1rem;
}
.infographic-pyfreeze .req-file-bar {
background: var(--paper); border-bottom: 1px solid var(--line); padding: 0.4rem 0.7rem;
font-weight: 700; color: var(--ink-soft); font-size: 0.72rem;
}
.infographic-pyfreeze .req-file-body { padding: 0.7rem 0.85rem; color: var(--ink); min-height: 5.5em; white-space: pre-line; }
.infographic-pyfreeze .req-file-body.is-empty { color: var(--ink-soft); font-style: italic; }
.infographic-pyfreeze .req-file-body .line { opacity: 0; animation: fr-fadein 0.25s ease forwards; display: block; }
@keyframes fr-fadein { from { opacity: 0; transform: translateX(-4px); } to { opacity: 1; transform: translateX(0); } }
.infographic-pyfreeze .fr-caption { text-align: center; font-size: 0.85rem; color: var(--ink-soft); }
@media (prefers-reduced-motion: reduce) {
.infographic-pyfreeze *, .infographic-pyfreeze *::before, .infographic-pyfreeze *::after {
animation-duration: 0.001ms !important; transition-duration: 0.001ms !important;
}
}
</style>
<div class="fr-wrap">
<h1>pip freeze > requirements.txt</h1>
<p class="fr-sub">Capture exactly what your project needs, so anyone can rebuild it.</p>
<p class="scenario">You've been building a small <strong>Flask app</strong>. Over the past few weeks you've installed a handful of packages into your virtual environment β you're ready to deploy, and the server needs the exact same ones.</p>
<div class="env-card">
<div class="env-bar">your virtual environment</div>
<div class="chip-row">
<span class="chip">Flask <span class="ver">3.0.3</span></span>
<span class="chip">requests <span class="ver">2.31.0</span></span>
<span class="chip">python-dotenv <span class="ver">1.0.1</span></span>
<span class="chip">gunicorn <span class="ver">22.0.0</span></span>
</div>
</div>
<div class="run-row"><button class="run-btn" id="runBtn">Run: pip freeze > requirements.txt</button></div>
<div class="arrow-down">β</div>
<div class="req-file">
<div class="req-file-bar">requirements.txt</div>
<div class="req-file-body is-empty" id="reqBody">(doesn't exist yet)</div>
</div>
<p class="fr-caption" id="frCaption">pip freeze lists every installed package with its exact version. The > sends that text straight into a file instead of printing it.</p>
</div>
<script>
(function () {
var root = document.currentScript.closest('.infographic-pyfreeze')
|| document.querySelector('.infographic-pyfreeze');
var bodyAttr = document.body.getAttribute('data-darkmode');
var dark;
if (bodyAttr === 'true') { dark = true; }
else if (bodyAttr === 'false') { dark = false; }
else {
var match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) root.setAttribute('data-theme', 'dark');
var packages = [
'Flask==3.0.3',
'requests==2.31.0',
'python-dotenv==1.0.1',
'gunicorn==22.0.0'
];
var runBtn = root.querySelector('#runBtn');
var reqBody = root.querySelector('#reqBody');
var frCaption = root.querySelector('#frCaption');
var ran = false;
runBtn.addEventListener('click', function () {
if (ran) return;
ran = true;
runBtn.disabled = true;
reqBody.classList.remove('is-empty');
reqBody.innerHTML = '';
packages.forEach(function (line, i) {
setTimeout(function () {
var span = document.createElement('span');
span.className = 'line';
span.textContent = line;
reqBody.appendChild(span);
if (i === packages.length - 1) {
frCaption.innerHTML = 'Now commit <strong>requirements.txt</strong> to your repo. On the server: <strong>pip install -r requirements.txt</strong> installs these exact versions β no guessing, no "works on my machine".';
}
}, i * 220);
});
});
})();
</script>
</div>