4 Claude Code settings I always change depending on the project I’m working on

4 Claude Code settings I always change depending on the project I’m working on


Up until a few months ago, most of us were using AI tools the same way. It didn’t really matter which one. You opened a box, typed a prompt, and hoped for the best. There wasn’t all that much to configure within each tool, and even if there was, only power users with the highest-tier plans ever bothered to touch them. For everyone else, the settings menu was more or less decorative and the defaults stayed well, the defaults. The tool behaved the same way in every project, for every person, every time, and the only factor that differentiated you and someone else was the quality of the prompt you would feed the tool.

After a few months of playing around with Claude Code, I started poking around in the settings I had previously spent months ignoring. I began by digging through Claude Code’s own documentation, then through Boris Cherny’s setup, then through the community’s setup, and I kept going and going. Thanks to all that digging, here are a couple of settings I change every single time I start a new project.

Permissions come first, every time

Deciding how much rope to give it

Every Claude Code project you work on is different. You might have a project you open every single day and run one certain skill where you hit the Enter key again and again, approving the same handful of commands you’ve already approved a hundred times. On the other hand, you might have another project where you’d never want Claude running anything without checking with you first. Those two projects can’t share a permission setup, which is why the very first thing I do is set the permission rules for that specific project.

The lever I reach for first is the permission mode. This is the thing that decides how Claude behaves before I’ve written a single rule, and Claude Code ships with a handful of them. You can set the one a project defaults to with defaultMode in that project’s .claude/settings.json, or just flip between them mid-session with Shift+Tab.

The default mode is exactly what it sounds like: Claude asks the first time it wants to use each tool, then remembers your answer. It’s fine, and for a brand-new project I don’t know well yet, it’s usually where I start. But “asks the first time” is doing a lot of quiet work in that sentence, because on a project where I’m making a hundred edits in a row, the first-time prompts stack up fast.

That’s when I switch to acceptEdits. This one automatically accepts file edits and the common filesystem commands you’d otherwise approve on autopilot anyway (mkdir, touch, mv, cp) as long as they’re inside my working directory. It’s the mode I spend most of my time in once I trust what Claude’s doing.

When I’m doing the opposite and poking at a codebase I don’t understand yet, I go the other direction into Plan mode. In Plan mode, Claude reads files and runs read-only commands to explore, but it won’t touch your source files. It just tells you what it would do. I use this constantly on unfamiliar projects, because it lets me watch Claude’s reasoning and catch a wrong turn while it’s still a paragraph of text instead of a bad commit.

There are a few more modes worth knowing about even if you reach for them less often. There’s a newer auto mode, currently a research preview, that auto-approves tool calls but runs background safety checks first to verify the action actually matches what you asked for. There’s dontAsk, which flips the logic around and auto-denies anything you haven’t pre-approved. And then there’s bypassPermissions, which does what the name promises and runs everything without asking.

Claude Code deny rules are what actually enforce a boundary

Saying no and meaning it

4 Claude Code settings I always change depending on the project I’m working on

Whenever I wanted Claude Code to keep away from a specific file or command, I used to just tell it to within my prompt or in the CLAUDE.md file I created for that project. While it worked most of the time, it decided not to work every so often, and I couldn’t work out why a rule I wrote so clearly kept getting ignored.

What I understood later is that an instruction in your prompt or CLAUDE.md only shapes what Claude tries to do. It doesn’t change what Claude Code will actually let it do. If you’re thinking “what about the permission modes you just mentioned,” they are broad by design. They change how often Claude stops to ask before it acts, which isn’t the same thing as putting a specific file or command permanently out of reach. That’s where Deny rules come in.

Deny rules live in the same permissions block in .claude/settings.json as your allow rules, and they do what they say: they stop Claude from using a specified tool or touching a specified path. The reason they’re reliable comes down to how Claude Code evaluates rules. It checks deny first, then ask, then allow, and the first match wins. That order is the whole point. A deny rule can’t carry exceptions, meaning if you deny something, no allow rule anywhere, at any settings level, can quietly override it.

What I actually put in there depends entirely on the project, which is why this is a per-repo setting and not a set-once one. On anything with secrets, the first entry is a rule to keep Claude away from environment files — Read(.env) blocks reading any .env at or below the current directory, so credentials never end up in context in the first place. On a project where I never want Claude pushing to a shared branch, Bash(git push *) in the deny list means it can commit all day, but the push always stops at me.

The right model depends on what you’re actually doing

Stop sending Opus to do Haiku’s job

terminal window showing claude code editor with syntax highlighting on a tablet device

A while back, I did an audit of my Claude Code usage. I found that the reason why I was burning through my limits so incredibly fast was because I was using Opus for almost every task I’d throw at it, including the ones that didn’t need anything close to that much firepower.

Claude Code lets you choose between four models (Fable, Opus, Sonnet, and Haiku) and the reason they all exist is that they sit at different points on the same trade-off between how capable a model is and how much time and money it costs you to run it. While “money” shouldn’t technically affect you if you use Claude Code via a subscription, it translates directly into how fast you burn through your usage limits. Once I started actually matching the model to the work in front of me instead of defaulting to the heaviest option, the whole thing got faster and cheaper, in terms of how much of my usage I was spending, without getting noticeably worse.

Haiku is the fast, cheap one meant for simple tasks, and it’s perfect for mechanical stuff like renaming things, small edits, work where you don’t need the model to sit and reason. Sonnet is the everyday coding model, and it’s where I spend most of my time on a normal project now. Opus is the one to reach for on complex reasoning, the tangled bugs and architectural decisions where you want it to think harder before it acts. And then there’s Fable, which is the newest and the most capable model in Claude Code. It’s built for long autonomous sessions where it investigates before acting and verifies its own work more than smaller models do. While Fable is incredibly powerful, it’s also the most expensive model to run, so it burns through your usage noticeably faster than the others.


laptop screen displaying code editor with terminal window showing html and css programming


I use OpenCode over Claude Code, and it’s every bit as good

Beat-for-beat, feature-for-feature.

Switching between them is as simple as it gets, which is what makes this a per-project habit rather than a one-time decision. You can run /model mid-session to open the picker, or type /model sonnet to jump straight there, and as of recent versions that choice sticks as your default for new sessions too. There’s also a neat hybrid worth knowing about called opusplan, which uses Opus while you’re in plan mode and then automatically drops to Sonnet once you move into actually writing the code. It’s a nice way to get Opus’s thinking for the planning without paying Opus’s rate for the whole session.

Then there’s how hard it thinks

How hard should it think about this?

claude code displayed on terminal window on mac laptop surrounded by colorful cartoon cats(1)

The second dial, and the one I ignored for far too long, is the effort level. Where the model decides how capable the reasoning is, the effort level decides how much of it happens on any given step, and it runs from low through medium, high, and xhigh up to max.

Lower effort is faster and cheaper for straightforward tasks, whereas higher effort gives you deeper reasoning for the genuinely hard ones. The default is high, which suits most coding tasks, and the mistake is often leaving it high when the task doesn’t need it. There’s no point burning thinking tokens on something trivial, and max in particular, can start overthinking and showing diminishing returns, so it’s worth testing before you lean on it. You set it with /effort, and the current level shows up next to the spinner so you can see at a glance what you’re running.

If you don’t want to commit to a session-wide setting for one tricky prompt, there’s a shortcut I use constantly: drop the word ultrathink anywhere in your message and Claude Code will reason more deeply on just that turn, without changing your effort setting for everything else. It’s the right tool for the one gnarly question in an otherwise ordinary session. However, it’s worth noting that only ultrathink triggers this, so writing “think harder” or “think more” does nothing but pad your prompt.

These are just a few of the settings I change from one project to the next, and they’re where I’d tell anyone to start. The specifics will always depend on what you’re working on, which is the whole reason they’re worth revisiting instead of setting once. Get into the habit of tuning them per project, and Claude Code stops guessing and starts feeling like it actually knows your repo.



Source link

Leave a Reply

Your email address will not be published. Required fields are marked *