How to Make Claude Code Use Specific (2026)
When Claude Code generates code for your project, it sometimes selects library versions that conflict with your existing dependencies or fail on your environment. Getting Claude to use specific library versions requires explicit configuration and clear communication. This guide shows you practical methods to ensure Claude Code respects your version requirements.
Why Library Version Control Matters
Mismatched library versions cause deployment failures, runtime errors, and hours of debugging. A common scenario: Claude generates code using the latest pandas 2.2.0 features, but your production environment runs pandas 1.5.3. The code works perfectly on Claude’s suggested setup and fails completely in production.
Controlling library versions becomes especially important when working with specialized skills. The frontend-design skill might suggest React 19, but your codebase requires React 18. Similarly, the pdf skill could reference a newer version of a PDF library than what your project supports. Version control prevents these mismatches.
The problem is structural, not a bug in Claude. Claude’s training data includes documentation, tutorials, and code samples from across the web, skewed toward recent and widely-cited content. When you ask it to write a data processing script without context, it defaults to patterns from recent library versions because that’s what most of the training examples use. It doesn’t know your production environment has a two-year-old pandas installation unless you tell it.
Specifying Versions in Your Project Files
The most reliable method is adding version constraints directly to your dependency files before asking Claude to generate code.
Python Projects
In your requirements.txt, use exact versions or version ranges:
Exact version pinning
requests==2.31.0
numpy==1.26.3
pandas==2.1.4
Minimum version (Claude will use at least this version)
flask>=2.3.0
Compatible release operator (~= allows patch updates within the same minor)
pydantic~=2.5.0
Exclude specific versions
django!=4.1.0
Create a requirements.txt file before starting your Claude Code session. When you explain your project, mention: “Our project uses pandas==2.1.4 and numpy==1.26.3. Please ensure any generated code is compatible with these versions.”
For more complex Python projects, use pyproject.toml:
[project]
dependencies = [
"requests>=2.31.0,<3.0.0",
"numpy==1.26.3",
"pandas==2.1.4",
]
The tdd skill often generates test code that imports your existing dependencies, version pinning ensures compatibility.
Locking Dependencies with pip-tools
For production Python projects, exact version pinning in requirements.txt is a starting point, but it doesn’t lock transitive dependencies. A package you pin directly might pull in a newer version of one of its own dependencies, which can still break your build.
pip-tools solves this by generating a fully locked requirements.txt from a lightweight requirements.in file:
requirements.in. human-maintained, loosely constrained
requests>=2.28.0
pandas==2.1.4
fastapi>=0.100.0
Run pip-compile requirements.in and it outputs a requirements.txt that pins every package in the entire dependency tree, including transitive dependencies:
Auto-generated by pip-tools
annotated-types==0.6.0
anyio==4.2.0
certifi==2023.11.17
fastapi==0.109.0
pandas==2.1.4
...
When you share this locked file with Claude Code, it has the full picture of what’s installed in your environment. Mentioning the requirements.txt contents (or pasting the relevant lines) when starting a session removes any ambiguity about which API surfaces are available.
Node.js Projects
In package.json, specify exact versions or ranges:
{
"dependencies": {
"express": "4.18.2",
"lodash": "4.17.21",
"axios": "^1.6.0"
},
"devDependencies": {
"jest": "29.7.0",
"typescript": "5.3.3"
}
}
The caret (^) allows minor and patch updates. For strict control, use exact versions like "express": "4.18.2".
Understanding npm Version Semantics
The version range operators in package.json have specific meanings that affect what Claude Code will suggest:
| Operator | Example | Meaning |
|---|---|---|
| Exact | "4.18.2" |
Only this version |
Caret ^ |
"^4.18.2" |
Compatible with 4.x.x (no major bumps) |
Tilde ~ |
"~4.18.2" |
Compatible with 4.18.x (no minor bumps) |
| Greater than | ">=4.0.0" |
Any version 4.0.0 or later |
| Range | ">=4.0.0 <5.0.0" |
Between 4.0.0 and 5.0.0 exclusive |
For projects in active production, the caret is a reasonable default for most dependencies because it allows security patches without breaking changes. For critical libraries where even minor API changes are a risk, use exact pinning. The package-lock.json file locks transitive dependencies completely. always commit it to version control and never delete it unless you’re intentionally updating your full dependency tree.
When you want Claude Code to match your locked state exactly, paste the relevant section of package-lock.json or tell it your Node.js version alongside your package versions. Node version matters because some packages ship different builds for different Node runtimes.
Using Claude Code’s Custom Instructions
Add version requirements to your project’s CLAUDE.md file. This file sits in your project root and gets loaded automatically at the start of each Claude Code session.
Create or update CLAUDE.md in your project root:
Project Configuration
Library Version Requirements
- Python 3.11
- Django 4.2.x (not Django 5.x)
- PostgreSQL 14.x
- All dependencies must be pinned in requirements.txt
Important Notes
When generating code, use only the library versions specified in requirements.txt.
Do not suggest upgrading library versions without explicit approval.
The supermemory skill can help you track which versions work across different projects.
A well-maintained CLAUDE.md is the single most impactful thing you can do for version control. Because it loads automatically, you don’t have to remember to state your constraints at the start of every session. Consider adding your full dependency list as a reference section, not just the high-level constraints. Claude Code reads this file before responding to any request, so making it comprehensive reduces the chance of version drift in any generated code.
Here’s a more detailed example for a production Python web service:
Project: Billing API
Runtime Environment
- Python 3.11.7
- Ubuntu 22.04 (production), macOS 14 (development)
- PostgreSQL 14.10
Dependency Constraints
Core dependencies are pinned in requirements.txt. Do not suggest version upgrades
unless explicitly asked. Key constraints:
- Django 4.2.x (LTS). do NOT suggest Django 5.x features
- psycopg2-binary 2.9.9. psycopg3 is not yet deployed
- celery 5.3.x. task signatures changed in 5.4, not yet migrated
- stripe 7.x. billing integration is certified against this version
API Patterns
Use Django class-based views. Avoid async views. our WSGI deployment doesn't support them.
The notes about what NOT to use are just as important as what to use. Claude Code will sometimes suggest async patterns, newer API shapes, or features from library versions it has seen frequently in training data. Explicit prohibitions in CLAUDE.md prevent those suggestions without you needing to correct them after the fact.
Communicating Version Requirements to Claude
Beyond configuration files, verbal communication works. When starting a session, explicitly state your version constraints:
“I’m working with a Python 3.11 project using Django 4.2.8 and PostgreSQL 14. Please generate code compatible with these versions.”
“Our Node.js project runs on Express 4.18 and Node 18. Use only those versions when suggesting dependencies.”
This approach works well when combined with the webapp-testing skill, which validates generated code against your specific environment.
If you’re in the middle of a session and Claude has already generated version-mismatched code, correct it explicitly rather than hoping the next suggestion will match. Something like: “That code uses the pandas 2.0 .convert_dtypes() behavior. We’re on pandas 1.5.3. Please rewrite it to be compatible.” Claude Code responds well to specific correction. naming the library, the version mismatch, and the target version gives it enough context to fix the code precisely.
Handling Version Conflicts in Generated Code
Sometimes Claude generates code using a library version you don’t have. When this happens:
- Check the import statements - Look for version-specific APIs
- Search for version announcements -
__version__attributes or changelogs - Downgrade or upgrade - Update your dependencies to match
A practical example: Claude generates code using pandas 2.0+ features like the new nullable integer dtype:
import pandas as pd
This requires pandas 2.0+
series = pd.array([1, 2, None], dtype="Int64")
Your project uses pandas 1.5.3. Replace with:
import pandas as pd
Compatible with pandas 1.5.3
series = pd.Series([1, 2, None], dtype="float64")
Identifying Version-Specific Code Patterns
Some changes between library major versions are obvious from imports or method names. Others are subtle behavioral differences. Here are common patterns to watch for when reviewing Claude-generated code against your pinned versions:
Python. pandas 1.x vs 2.x
pandas 2.x. copy_on_write semantics; modifying a slice doesn't warn
df_subset = df[df['value'] > 0]
df_subset['label'] = 'positive' # works silently in 2.x
pandas 1.x. this triggers SettingWithCopyWarning
use .copy() explicitly
df_subset = df[df['value'] > 0].copy()
df_subset['label'] = 'positive'
Python. SQLAlchemy 1.x vs 2.x
SQLAlchemy 2.x style
with Session(engine) as session:
result = session.execute(select(User).where(User.id == user_id))
user = result.scalar_one()
SQLAlchemy 1.x style
with Session(engine) as session:
user = session.query(User).filter(User.id == user_id).one()
Node.js. Express 4.x vs 5.x
// Express 5.x. async errors auto-forwarded to error handler
app.get('/user/:id', async (req, res) => {
const user = await db.findUser(req.params.id);
res.json(user);
});
// Express 4.x. must explicitly catch and pass to next()
app.get('/user/:id', async (req, res, next) => {
try {
const user = await db.findUser(req.params.id);
res.json(user);
} catch (err) {
next(err);
}
});
When Claude generates code in a session where you’ve specified version constraints, review these structural patterns before running anything. Version-specific idioms often look syntactically valid but fail at runtime.
Using Virtual Environments
Create a virtual environment with your specific versions before running Claude-generated code:
Create and activate virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
Install pinned versions
pip install -r requirements.txt
Verify versions
pip list | grep -E "(requests|numpy|pandas)"
This isolates your project’s dependencies and prevents Claude’s suggestions from affecting your global Python installation.
For teams managing multiple Python projects with different version requirements, pyenv adds an extra layer of isolation by controlling the Python interpreter version itself:
Install a specific Python version
pyenv install 3.11.7
Set it as the local version for this project directory
pyenv local 3.11.7
Confirm active version
python --version # Should output Python 3.11.7
Create a virtual environment using this interpreter
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
The .python-version file that pyenv local creates can be committed to version control. When a teammate runs pyenv local in the same directory, they automatically use the same Python version you’ve specified. This closes the gap between “works on my machine” and “works in CI.”
For Node.js projects, nvm (Node Version Manager) provides equivalent control:
.nvmrc file in your project root
echo "18.19.0" > .nvmrc
Use the version specified in .nvmrc
nvm use
Install dependencies using the pinned Node version
npm ci
When you tell Claude Code you’re using a specific Node version, it avoids suggesting APIs that were introduced in later releases. Node 18 and Node 20 have meaningful differences in the fetch API availability and several built-in module behaviors.
Pro Tips for Version Control
- Lock files matter: Python projects benefit from
pip-toolsorpoetry.lock. Node projects should havepackage-lock.jsoncommitted. - Check skill-specific requirements: Skills like mcp-builder might require specific Node versions or package versions.
- Test generated code locally: Always run
pip install -r requirements.txtornpm installafter Claude generates significant code. - Version pins in code comments: When showing Claude code snippets from your project, include version comments:
Tested with: pandas==2.1.4, numpy==1.26.3
import pandas as pd
This signals to Claude which versions your code works with.
Share the output of pip list or npm list for critical sessions. When you’re working on something where version accuracy is essential. a deployment script, a data pipeline, an authentication flow. paste your current installed package list into the session context. It takes ten seconds and eliminates the entire class of “Claude suggested a 2.x API but we’re on 1.x” problems.
Use pip check before finalizing a Claude-generated requirements file. After accepting Claude’s dependency suggestions, run pip check to detect any incompatible combinations:
pip install -r requirements.txt
pip check
package-a 1.2.3 requires package-b>=2.0, but you have package-b 1.9.0
Claude Code can fix these conflicts if you share the pip check output. Tell it: “These are the dependency conflicts I see. Please resolve them while keeping the core packages at their specified versions.”
Summary
Making Claude Code use specific library versions requires a combination of:
- Pinning versions in
requirements.txt,package.json, orpyproject.toml - Adding version requirements to your
CLAUDE.mdfile - Communicating verbally about version constraints at session start
- Using virtual environments to isolate and test versions
These methods ensure Claude generates code compatible with your production environment, reducing deployment issues and debugging time.
The most durable setup combines all four: pinned requirements.txt or package.json in version control, a CLAUDE.md with explicit constraints and prohibitions, a virtual environment or container that matches production, and the habit of stating your environment at the start of any session where version accuracy matters. Each layer reinforces the others. The configuration files load automatically, the CLAUDE.md provides context before any code is generated, and the runtime environment catches any gaps.
Try it: Paste your error into our Error Diagnostic for an instant fix.
Related Reading
- How to Make Claude Code Respect Module Boundaries
- Claude Code Gives Incorrect Imports How to Fix
- How to Write Effective CLAUDE.md for Your Project
- Claude Skills Guides Hub
Built by theluckystrike. More at zovo.one
Find the right skill → Browse 155+ skills in our Skill Finder.