
If you've been using Claude Code like a smarter tab-completion, you're leaving most of its value on the table. This is a practical guide for developers who want Claude to behave like a senior teammate — one who already knows your codebase conventions, runs your tests, and doesn't break things in files you didn't ask it to touch.
The Problem: Claude Doesn't Know Your Project Rules
Out of the box, Claude Code has no idea how your project is structured. It doesn't know whether you prefer functional patterns over classes, which directory holds your integration tests, or that you're running Node 20 with strict TypeScript.
So it guesses. And it guesses wrong in the same ways, over and over. You end up re-explaining context on every session — burning tokens and time re-orienting the model before you get anything useful done.
The first thing I tried was putting all the context in the prompt itself. That worked for one session but didn't survive a conversation reset, and long preambles eat into your context window fast.
Section 1: CLAUDE.md — Persistent Project Context
The fix is a CLAUDE.md file at your project root. Claude Code reads this automatically at the start of every session. Think of it as an onboarding doc for an AI contributor — the kind of thing you'd write for a new hire so they don't have to ask the same questions twice.
What belongs in CLAUDE.md:
- Tech stack and versions
- How to run tests
- Coding conventions (functional vs. OOP, naming patterns, lint rules)
- Folder structure and what lives where
- Things Claude must not touch (generated files, migration files, etc.)
Here's a minimal example for an n8n + TypeScript project:
# CLAUDE.md
## Tech Stack
- Runtime: Node.js 20, TypeScript (strict mode)
- Workflow engine: n8n (self-hosted)
- Test runner: Jest (`npm test`)
## Coding Style
- Prefer functional programming — avoid classes unless extending an n8n node
- Use named exports, not default exports
- All async functions must handle errors explicitly (no silent catches)
## Folder Structure
- src/nodes/ → custom n8n node definitions
- src/utils/ → pure utility functions (no side effects)
- src/__tests__/ → Jest test files, mirror the src/ structure
## Off-limits
- Do NOT edit anything under dist/ — that's compiled output
- Do NOT modify *.migration.ts files without explicit instruction
After adding this, I stopped losing context between sessions. Claude picked up conventions correctly on the first try instead of the third. My rough estimate: about 40% less time spent correcting the model's assumptions before actual work starts.
Section 2: Writing Commands That Actually Work
"Write me some code" is the worst prompt you can give an agent. It hands Claude a blank canvas with no constraints — and unconstrained AI output in a real codebase is a liability, not an asset.
The pattern that works for me is a two-step command structure:
Step 1: Orient before acting. Have Claude map the relevant part of the codebase before touching anything.
claude "List the files in src/auth/ and describe what each one does"
Step 2: Targeted action with explicit scope.
claude "Analyze the token expiry logic in src/auth/auth.ts and suggest a fix for the refresh race condition"
Notice the difference: the second command names the file, names the problem, and names the specific behavior. Claude can't drift into an unrelated module because you've drawn the boundary.
When you're working with n8n specifically, the equivalent is scoping to a workflow node or a specific trigger:
claude "Look at the HTTP Request node in workflows/slack-notifier.json and explain why it might return 401 on retry"
Section 3: Closing the Loop with Automated Verification
A code change that isn't verified is a liability. This is where most AI-assisted workflows fall apart — the model produces output, the developer does a quick scan, ships it, and discovers the bug in staging.
The fix is to make test execution part of the command itself.
claude "Fix the null reference in user_service.py on line 84 and run pytest to verify"
Or for a TypeScript project:
claude "Refactor the token validation in auth.ts to use the new JWTConfig type, then run npm test and show me the output"
What you're doing here is turning Claude into a small feedback loop: change → test → report. If the tests fail, Claude sees the output and can iterate. You're not shipping until green.
For n8n workflows, where you can't always run automated tests, a useful alternative is asking Claude to validate the JSON schema before you import:
claude "Check this workflow JSON against n8n's node schema and flag any missing required fields"
Variations and Gotchas
CLAUDE.md placement matters. Claude Code looks for the file in the project root — the directory where you run claude. If you're running it from a subdirectory, it won't find a root-level CLAUDE.md. Either run from root or add a local CLAUDE.md to the subdirectory.
Don't over-specify in commands. There's a balance between scoped and over-constrained. If you write a 10-line command with five "do not" clauses, Claude starts satisfying the constraints rather than solving the problem. Keep commands focused on one outcome.
Mac vs. Linux path differences. If your CLAUDE.md references shell commands like find or ls, behavior differs between macOS (BSD) and Linux (GNU). Where it matters — especially in CI — use Node scripts or npx commands instead of raw shell.
Docker environments. If Claude Code is running inside a container, make sure your CLAUDE.md test commands match what's available in that container. npm test means nothing if the container image doesn't have node_modules pre-installed. Point to your container's entrypoint script instead:
## Test Command (Docker)
docker exec app_container npm test
| Environment | Test Command Pattern | Gotcha |
|---|---|---|
| Local Mac/Linux | npm test / pytest |
Works directly |
| Docker | docker exec <container> <cmd> |
Container must be running |
| CI (GitHub Actions) | Defined in workflow YAML | Claude can't trigger this directly |
| n8n (no unit tests) | JSON schema validation | Manual or custom script |
Closing
The shift that matters here isn't learning new Claude Code features — it's treating the model as a stateful agent rather than a prompt box. CLAUDE.md gives it memory of your project. Scoped commands give it a working boundary. Test-gated commands give it a feedback loop.
Set those three things up and you're not using AI to write code faster — you're using it to ship safer.
Next worth exploring: hooking n8n's error log webhook directly into a Claude Code command so the whole detect → analyze → fix cycle runs without you in the loop.
TAGS: claude-code, n8n, ai-development, productivity, typescript
🐦 Faster updates on X: @baegseungh7061
📚 More in this series: Code Practical
💌 Subscribe: Follow on X or grab the RSS
댓글
댓글 쓰기