A production-ready starter template for Claude Code. Get a fully configured setup in minutes instead of hours.
Required:
- Claude Code CLI installed and authenticated
- Bash 3.2+ (macOS default works)
- Git
- jq - JSON parsing in hooks (
brew install jq/apt install jq)
Optional (for formatting hooks):
- Your language's formatter: prettier, black/ruff, gofmt, rustfmt, rubocop, mix format
Check your setup:
claude --version # Should show Claude Code version
bash --version # Should be 3.2+ (macOS default works)
jq --version # Required for hooks| Component | Requirement | Notes |
|---|---|---|
| OS | Linux, macOS | Tested on Ubuntu 22.04+, macOS 13+ |
| Bash | 3.2+ | macOS default (3.2) works fine |
| jq | Any version | Required for hooks |
| Claude Code | Any version | Tested with 1.x |
Stack-specific formatters (optional):
| Stack | Formatter | Install |
|---|---|---|
| TypeScript | prettier | npm i -g prettier |
| Python | black, ruff | pip install black ruff |
| Go | gofmt | Included with Go |
| Rust | rustfmt | rustup component add rustfmt |
| Ruby | rubocop | gem install rubocop |
| Elixir | mix format | Included with Elixir |
Most developers install Claude Code and use maybe 10% of its capabilities. This repo gives you:
- Stack-specific presets - TypeScript, Python, Go, Rust, Ruby, Elixir configurations
- Security by default - Blocked sensitive files, dangerous command prevention
- Custom skills - Reusable commands like review, test, explain
- Specialized agents - Subagents for research, code review, test writing
- Pre-commit review - Forces you to understand what you're committing
- Auto-formatting - Runs your formatter after every edit
- Version detection - Reads from
.tool-versionsautomatically
brew tap zbruhnke/claude-code-starter
brew install claude-code-starterUpdate:
brew upgrade claude-code-startercurl -fsSL https://raw.githubusercontent.com/zbruhnke/claude-code-starter/main/install.sh | bashThis installs ccs (short alias) and claude-code-starter (full name) to your PATH.
The installer automatically verifies SHA256 checksums when available (v0.7.0+).
Update:
ccs updatePin to a specific version:
curl -fsSL https://raw.githubusercontent.com/zbruhnke/claude-code-starter/main/install.sh | bash -s -- --version <version>See it work end-to-end:
# 1. Install the CLI (if you haven't already)
curl -fsSL https://raw.githubusercontent.com/zbruhnke/claude-code-starter/main/install.sh | bash
source ~/.zshrc # or restart your terminal
# 2. Create your project and configure it
mkdir my-app && cd my-app
git init
ccs init # Pick TypeScript, accept defaults
# 3. Create something to work with
mkdir -p src && echo "export const hello = () => 'world';" > src/utils.ts
git add -A
# 4. Start Claude Code
claudeNow in Claude Code:
> Review my staged changes
# → Claude runs code-review skill, analyzes src/utils.ts
> Add a helper function to validate emails in src/utils.ts
# → After edit, auto-format hook runs prettier automatically
> Stage and commit these changes
# → Pre-commit hook shows diff, Claude explains before committing
That's the core loop: edit → auto-format → review → commit with understanding.
mkdir my-project && cd my-project
git init
ccs initcd your-existing-project
ccs initccs adopt # Interactive mode - choose what to install
ccs adopt all # Install core: skills, agents, hooks, rules, security
ccs adopt skills # Just skills
ccs adopt agents # Just agents
ccs adopt precommit # Pre-commit review hook
ccs adopt security # Security config only
ccs adopt stack # Stack-specific presetNote:
adopt allinstalls core components but NOT stack presets or precommit hook (since those are project-specific choices). Use interactive mode or add them explicitly.
ccs help # Show all commands
ccs init # Interactive setup
ccs adopt [component] # Add components
ccs update # Update to latest version
ccs version # Show versionNote:
claude-code-starteralso works as the full command name.
The setup script will:
- Ask which stack you're using (TypeScript, Python, Go, Rust, Ruby, Elixir)
- Auto-detect versions from
.tool-versionsif present - Ask for your project name and description
- Ask for your dev/test/build commands
- Select components to install (rules, skills, agents, hooks)
- Generate all configuration files
Manual installation without the CLI
git clone https://github.com/zbruhnke/claude-code-starter.git ~/claude-code-starter
cd your-project
~/claude-code-starter/setup.sh# Download and verify (recommended)
VERSION="v0.8.3" # Check releases for latest
TARBALL="claude-code-starter-${VERSION#v}.tar.gz"
curl -fsSL "https://github.com/zbruhnke/claude-code-starter/archive/refs/tags/${VERSION}.tar.gz" -o "$TARBALL"
curl -fsSL "https://github.com/zbruhnke/claude-code-starter/releases/download/${VERSION}/checksums.txt" -o checksums.txt
# Verify checksum before extracting
grep "$TARBALL" checksums.txt | sha256sum -c -
# Extract and run
tar -xzf "$TARBALL"
cd your-project
~/claude-code-starter-${VERSION#v}/setup.sh# Core files
cp CLAUDE.template.md your-project/CLAUDE.md
cp .claudeignore your-project/
cp -r .claude your-project/
# Stack-specific preset (requires jq for settings merge)
cp stacks/typescript/CLAUDE.md your-project/CLAUDE.md
jq -s '.[0] as $core | .[1] as $stack | {permissions: {allow: ($core.permissions.allow + $stack.permissions.allow), deny: ($core.permissions.deny + $stack.permissions.deny)}, hooks: $core.hooks}' \
.claude/core-settings.json stacks/typescript/stack-settings.json > your-project/.claude/settings.jsonNote: Stack templates contain
{{PLACEHOLDER}}variables. Manual copies require replacing these yourself.
| Topic | Description |
|---|---|
| Skills | Creating and using custom skills |
| Agents | Specialized subagents for focused tasks |
| Hooks | Automation via PreToolUse/PostToolUse |
| Permissions | Allow/deny rules and patterns |
| PR Reviews | Automated CI/CD code reviews |
Current status: Pre-release. The file structure and core concepts are stable, but details may change.
What's stable:
- File structure (
.claude/,CLAUDE.md,.claudeignore) - Skill and agent YAML frontmatter format
- Hook input/output contract (JSON on stdin, exit codes)
- Permission pattern syntax
What may change:
- Setup script prompts and flow
- Default permissions in presets
- Included skills/agents/rules content
For reproducible installs, pin to a specific version:
curl -fsSL https://raw.githubusercontent.com/zbruhnke/claude-code-starter/main/install.sh | bash -s -- --version <version>Upgrade to latest:
ccs updateThis downloads the latest release while preserving your project's CLAUDE.md and .claude/settings.local.json.
See Releases for all versions.
your-project/
├── CLAUDE.md # Project context (Claude reads this first)
├── CLAUDE.local.md # Personal context (gitignored)
├── .claudeignore # Files to exclude from Claude's context
├── .claude/
│ ├── settings.json # Permissions, hooks, environment
│ ├── settings.local.json # Personal overrides (gitignored)
│ ├── rules/ # Reference documentation (NOT auto-loaded)
│ │ ├── code-style.md
│ │ ├── git.md
│ │ ├── quality-gates.md
│ │ ├── security.md
│ │ ├── security-model.md
│ │ └── testing.md
│ ├── skills/ # Custom skill definitions
│ │ ├── code-review/SKILL.md
│ │ ├── explain-code/SKILL.md
│ │ ├── generate-tests/SKILL.md
│ │ ├── install-precommit/SKILL.md
│ │ ├── refactor-code/SKILL.md
│ │ ├── refresh-claude/SKILL.md
│ │ ├── review-mr/SKILL.md
│ │ ├── wiggum/SKILL.md
│ │ ├── changelog-writer/SKILL.md
│ │ ├── release-checklist/SKILL.md
│ │ └── risk-register/SKILL.md
│ ├── agents/ # Specialized subagents
│ │ ├── researcher.md
│ │ ├── code-reviewer.md
│ │ ├── code-simplifier.md
│ │ ├── test-writer.md
│ │ ├── documentation-writer.md
│ │ └── adr-writer.md
│ └── hooks/ # Automation scripts
│ ├── validate-bash.sh
│ ├── auto-format.sh
│ └── pre-commit-review.sh
In the starter repo only (not copied to your project):
stacks/ # Stack presets used by setup.sh
├── typescript/
├── python/
├── go/
├── rust/
├── ruby/
└── elixir/
This is the most important file. Claude reads it at the start of every session. Changes made during a session require restarting Claude to take effect.
What to include:
- Project name and one-line description
- Tech stack with specific versions
- Commands to run (dev, test, build, lint)
- Code conventions specific to YOUR project
- Things Claude should NEVER do
Example:
# Acme API
REST API for the Acme e-commerce platform.
## Tech Stack
- Python 3.11
- FastAPI 0.104
- PostgreSQL 15 via SQLAlchemy
- Redis for caching
## Commands
make dev # Start with hot reload
make test # Run pytest
make lint # ruff + mypy
## Conventions
- Use Pydantic models for all request/response schemas
- Async everywhere - no sync database calls
- All endpoints need OpenAPI descriptions
## Do Not
- Never use raw SQL - always SQLAlchemy
- Never commit .env files
- Don't add print statements for debugging (use logging)Tips:
- Keep it under 500 lines
- Be specific, not generic
- Update it when you learn Claude makes mistakes
Skills are reusable instruction sets that Claude applies via semantic matching. Describe what you want, and Claude applies the relevant skill automatically.
Included skills: code-review, explain-code, generate-tests, refactor-code, review-mr, install-precommit, wiggum, refresh-claude, changelog-writer, release-checklist, risk-register
Example usage:
"Review my staged changes" # Triggers code-review skill
"Explain how src/utils.py works" # Triggers explain-code skill
"Generate tests for UserService" # Triggers generate-tests skill
→ Full documentation: docs/skills.md
Agents are focused AI assistants with limited tool access, useful for delegating specific tasks.
Included agents: researcher (read-only exploration), code-reviewer, code-simplifier, test-writer, documentation-writer, adr-writer
Example usage:
Use the researcher agent to understand how authentication works
Use the test-writer agent to generate tests for UserService
→ Full documentation: docs/agents.md
Hooks run scripts at specific points in Claude's workflow for validation and automation.
Included hooks:
validate-bash.sh- Block dangerous shell commands (PreToolUse)auto-format.sh- Run formatter after file edits (PostToolUse)pre-commit-review.sh- Review changes before git commits
→ Full documentation: docs/hooks.md
Control what Claude can and cannot do via allow/deny rules in .claude/settings.json.
Default posture: Safe operations allowed (git, ls, pwd), dangerous operations denied (rm -rf, sudo, .env access). Unlisted commands prompt for approval.
Configuration scopes:
.claude/settings.json- Team defaults (committed).claude/settings.local.json- Personal overrides (git-ignored)
→ Full documentation: docs/permissions.md
What this protects against:
- Accidental exposure of
.envfiles and secrets - Recursive deletions (
rm -rf) - Privilege escalation (
sudo) - Remote code execution (
curl | bash) - Overly permissive file modes (
chmod 777)
What this does NOT protect against:
- Determined adversarial use (variables, encoding, indirect access)
- Secrets exposed through logs, test output, or your own code
- Network exfiltration if your app makes API calls
- Reading sensitive files via allowed commands
This is a safety net, not a security boundary. A sophisticated user can bypass these protections. See .claude/rules/security-model.md for full details including bypass techniques and hardening recommendations.
Permissions follow a deliberate escalation model:
| Layer | Scope | Example |
|---|---|---|
| Base | Safe, non-destructive | git status, ls, pwd |
| Stack presets | Build/test/lint for your language | npm test, pytest, cargo build |
| Local overrides | Opt-in risky operations | rm, mv, file system writes |
Design principles:
- Claude prompts for unlisted commands (you approve once per session)
- Destructive operations (
rm -rf,sudo) are explicitly denied - Stack presets add only what's needed for that ecosystem
- Personal preferences go in
.claude/settings.local.json(git-ignored)
This means a fresh install is safe by default. You expand permissions intentionally, not accidentally.
This starter includes a pre-commit review system that forces you to understand what you're committing.
Why this matters: When using AI coding assistants, it's easy to fall into "vibe coding" - accepting changes without really understanding them. The pre-commit review hook shows you:
- What files changed
- Summary of the changes
- Potential issues or concerns
- Requires you to confirm before committing
How it works:
$ git commit -m "Add user authentication"
┌─────────────────────────────────────────────────────────────┐
│ PRE-COMMIT REVIEW │
├─────────────────────────────────────────────────────────────┤
│ Files changed: 5 │
│ Lines added: 247 | Lines removed: 12 │
├─────────────────────────────────────────────────────────────┤
│ SUMMARY: │
│ Adding JWT-based authentication with login/logout │
│ endpoints and middleware for protected routes. │
│ │
│ NEED TO KNOW: │
│ • New dependency: jsonwebtoken │
│ • Environment variable required: JWT_SECRET │
│ • Breaking: /api/users now requires auth header │
│ │
│ POTENTIAL ISSUES: │
│ • Token expiry set to 7 days (consider shorter) │
│ • No refresh token implementation │
│ • Missing rate limiting on login endpoint │
└─────────────────────────────────────────────────────────────┘
Do you understand these changes and want to commit?
(y)es to commit, (n)o to abort, (d)iff to see full diff, (q)uitEnable the hook:
# The setup.sh script does this automatically, but manually:
cp .claude/hooks/pre-commit-review.sh .git/hooks/pre-commit
chmod +x .git/hooks/pre-commitNon-interactive mode (Claude Code, CI, GUI clients): The hook passes silently in non-TTY environments. When using Claude Code, Claude is instructed (via CLAUDE.md) to explain changes and ask for confirmation in the conversation before committing.
# Skip review entirely (emergency use)
SKIP_PRE_COMMIT_REVIEW=1 git commit -m "Emergency fix"The setup script includes presets for common stacks:
| Stack | Includes |
|---|---|
| TypeScript | npm/yarn commands, prettier, eslint, tsc |
| Python | pytest, ruff, black, mypy, uvicorn |
| Go | go test, golangci-lint, gofmt |
| Rust | cargo test, clippy, rustfmt |
| Ruby | rspec, rubocop, rails commands |
| Elixir | mix test, credo, format, Commanded/CQRS patterns |
Each preset includes:
stack-settings.jsonpermissions (merged withcore-settings.jsonduring setup)- Stack-specific CLAUDE.md template
- Relevant rules and patterns
- Auto-format hook for that language
If your project has a .tool-versions file (asdf/mise), the setup script automatically detects versions:
# .tool-versions
nodejs 20.10.0
python 3.11.4
elixir 1.15.7
These are used to populate your CLAUDE.md template. If no .tool-versions exists, it falls back to detecting from runtime commands (node --version, python3 --version, etc.).
Get AI-powered code reviews automatically on every pull request.
Quick start:
# Command line
./review-mr.sh # Review current branch
./review-mr.sh --pr 123 # Review GitHub PR
# GitHub Actions
cp .github/workflows/pr-review.yml your-repo/.github/workflows/
# Add ANTHROPIC_API_KEY to repo secrets
# GitLab CI
# Add to .gitlab-ci.yml: include: - local: 'ci/gitlab-mr-review.yml'
# Set ANTHROPIC_API_KEY and GITLAB_TOKEN in CI/CD variablesData handling: PR automation sends the diff, file paths, and commit messages to Anthropic's API. Don't enable on repos with secrets in code or where your security policy prohibits external API calls with code content.
→ Full documentation: docs/pr-reviews.md (includes detailed privacy guidance)
| File | Committed | Purpose |
|---|---|---|
CLAUDE.md |
Yes | Project context for team |
CLAUDE.local.md |
No | Personal context |
.claude/settings.json |
Yes | Team permissions/hooks |
.claude/settings.local.json |
No | Personal overrides |
.claude/rules/*.md |
Yes | Reference documentation |
.claude/skills/*/SKILL.md |
Yes | Custom commands |
.claude/agents/*.md |
Yes | Specialized subagents |
.claudeignore |
Yes | File exclusions |
chmod +x .claude/hooks/*.sh- Ensure directory structure is
.claude/skills/<name>/SKILL.md - Check YAML frontmatter has
name,description,tools,model
- Verify JSON structure in
settings.json(nestedhooksarray) - Check hook script is executable
- Test hook manually:
echo '{"tool_name":"Bash","tool_input":{"command":"ls"}}' | .claude/hooks/validate-bash.sh
Rules in .claude/rules/ are reference documentation, not automatically loaded instructions. Include critical rules directly in CLAUDE.md.
# Remove the installation
rm -rf ~/.claude-code-starter
# Remove PATH entry from your shell config (~/.zshrc, ~/.bashrc, etc.)
# Delete the lines containing "claude-code-starter"Note: These commands are for you (human). Claude Code is blocked from running
rm -rf.
# Core files
rm -rf .claude/
rm -f CLAUDE.md CLAUDE.local.md .claudeignore
# Git hook (if installed)
rm -f .git/hooks/pre-commit
# CI workflows (if copied)
rm -f .github/workflows/pr-review.yml
rm -f ci/gitlab-mr-review.ymlSecrets: Remove ANTHROPIC_API_KEY from your CI/CD secrets if you added it for PR reviews.
PRs welcome! See CONTRIBUTING.md for guidelines.
Quick quality check:
shellcheck --severity=warning setup.sh adopt.sh install.sh review-mr.sh bin/claude-code-starter lib/common.sh .claude/hooks/*.sh
for f in .claude/core-settings.json stacks/*/stack-settings.json; do jq . "$f" > /dev/null; doneSee SECURITY.md for our security policy and how to report vulnerabilities.
Need help? See SUPPORT.md for troubleshooting and how to get assistance.
MIT - See LICENSE