Getting Started with Claude Code

This content was generated with the assistance of AI and should be verified against the official documentation of each tool and framework before being relied on in production.

This section’s bibliography lists the reference material consulted while preparing these pages.

Examples on this page target the Claude Code CLI, checked against the official quickstart and permission-modes pages at https://code.claude.com/docs/en/ as of 2026-09-28. Running claude --version on a current native install prints a version number followed by (Claude Code); native installs update themselves automatically in the background, so the exact number keeps moving, and this page describes behavior rather than pinning one. The running example is the same DocsAssistant API used throughout this sub-section, a Spring Boot + Python sample whose Java sources live under src/main/java/com/example/docsassistant/.

Install and log in

The current recommended install is a single native-install command, one per platform, from the official quickstart (checked 2026-09-28):

macOS, Linux, WSL
$ curl -fsSL https://claude.ai/install.sh | bash
Windows PowerShell
$ irm https://claude.ai/install.ps1 | iex

Homebrew (brew install --cask claude-code) and WinGet (winget install Anthropic.ClaudeCode) are documented alternatives; unlike the native installer, those two do not auto-update, so brew upgrade claude-code or winget upgrade Anthropic.ClaudeCode has to be run manually. After installing, open a new terminal and confirm it worked:

$ claude --version

Claude Code needs an account. Starting a session with no arguments prompts you to log in on first use:

$ claude

Follow the browser prompts to authenticate with a Claude subscription (Pro, Max, Team or Enterprise) or a Claude Console account; if ANTHROPIC_API_KEY is set in the environment, Claude Code asks you to approve that key instead of prompting for a browser login. Once logged in, credentials are stored and later sessions skip this step. To switch accounts or re-authenticate, run /login inside a running session. See Claude Code — Quickstart.

The agentic loop

Claude Code’s own architecture page describes a single loop, not a fixed sequence of named stages: for any task it gathers context (reading files, searching, running read-only commands), takes action (editing files, running commands, using tools), and verifies results (running tests, re-reading changed files, checking output) — and these three phases interleave and repeat rather than running once each. A one-line question may only need the first phase; a bug fix typically cycles through all three multiple times, each result feeding the next decision, until the task is done or you interrupt it. You stay part of the loop throughout: pressing Esc stops the current tool call immediately, and typing a correction without stopping lets Claude read it as soon as the current tool calls finish.

flowchart LR P[Your prompt] --> G[Gather context] G --> A[Take action] A --> V[Verify results] V -->|task not done| G V -->|task complete| D[Done / waiting for you] P -.->|you can interrupt at any point| D

Referencing files with @

Typing @ opens a path-suggestion menu; press Tab or Enter to accept a highlighted path, then Enter again to send the message. An @ reference works on a single file, a whole directory (which shows a file listing, not its contents), or, in the form @server:resource, a resource exposed by a connected MCP server. Referencing a file also pulls in any CLAUDE.md in that file’s directory and its parent directories, which is why @ references are the fastest way to point Claude at the exact context a task needs instead of waiting for it to search the repository itself:

$ claude "explain the pagination logic in @src/main/java/com/example/docsassistant/DocsController.java"

Permission modes and plan mode

A permission mode sets what Claude can do without asking first. As of 2026-09-28, the CLI’s Shift+Tab cycles through the modes and the status bar names the active one; the ones most relevant when getting started are:

Mode (status bar label) What runs without a prompt

Manual (default)

Reads only; Claude asks before file edits and shell commands.

Accept edits (acceptEdits)

Reads, file edits and common filesystem commands (mkdir, mv, cp, and similar).

Plan (plan)

Reads and exploration only; edits stay blocked until you approve a plan.

Auto (auto)

Almost everything, with a separate classifier model reviewing actions in the background instead of asking you.

Depending on the Claude Code version, plan, and account, a new interactive session can start in Manual or in Auto mode by default; either way, Shift+Tab switches modes at any time. Plan mode specifically is entered by pressing Shift+Tab until the status bar shows ⏸ plan mode on, by prefixing a single prompt with /plan, or by starting the session directly in that mode:

$ claude --permission-mode plan

In plan mode Claude reads files and proposes a plan without editing anything; once it presents the plan you choose to approve it (switching the session into an editing mode), keep planning, or discard it. This is the foundation the sub-section’s own Plan-First Workflows page builds on. See Claude Code — Choose a permission mode.

Checkpoints and rewind

Claude Code snapshots the files its own editing tools touch before each prompt that starts a new turn, keeping the most recent checkpoints from the session. Running /rewind, or pressing Esc twice with an empty prompt input, opens a menu listing every earlier prompt in the session; picking one offers Restore code and conversation, Restore conversation only, Restore code only, or summarize the conversation from or up to that point:

$ claude
> /rewind

Checkpoints only cover files Claude’s own file-editing tools changed — a file a Bash command deleted, moved or overwrote (rm, mv, cp) is not tracked and cannot be restored this way, and checkpoints are not a replacement for Git history. See Claude Code — Checkpointing.

Sessions, IDE extensions, desktop and web

Every conversation is saved locally and tied to the directory it started in, so a task can span more than one sitting. claude --continue (or -c) reopens the most recent session in the current directory and appends to it; claude --resume (or -r) opens a picker (or takes a session ID or name directly) to resume a specific past session:

$ claude --continue
$ claude --resume "docs-endpoint"

Beyond the terminal, the same agentic loop and tools are available through the VS Code extension (a native panel with inline diffs, @-mentions with selected line ranges, and plan review before edits land), the JetBrains plugin (which runs Claude Code in the IDE’s own terminal, so Shift+Tab and --permission-mode behave exactly as on the CLI), the desktop app, and the web at claude.ai/code. Which interface you use changes only where the conversation is displayed and, for cloud sessions, where the code runs — the underlying loop, tools and checkpoints are the same everywhere. See Claude Code — Manage sessions for --continue, --resume and naming sessions, and Parallel Sessions & Worktrees for running several sessions side by side with git worktree.

The / command basics

Typing / inside a running session lists the available session commands; Tab completes a partial name. As of 2026-09-28 the everyday ones are:

Command What it does

/help

Shows available commands and how to get further help.

/clear

Starts a new conversation with an empty context window (aliased as /reset / /new); pass a name to label the conversation you’re leaving so /resume can find it again.

/compact

Frees up context by summarizing the conversation so far; takes optional focus instructions, e.g. /compact focus on the controller changes.

/model

Switches which Claude model the session uses, without restarting it.

/init

Generates a starter CLAUDE.md for the current project.

/rewind

Opens the checkpoint menu described above.

/context

Visualizes current context-window usage.

See Claude Code — Commands for the full list, and Managing Context for /compact and /context in more depth.

Example: adding an endpoint to DocsAssistant API

This is the same task, with the same contract, as Getting Started with GitHub Copilot's chat example: add a GET /api/pages/{id} endpoint to DocsController that returns the page as a PageDto, or a 404 with a JSON error body when no page has that id. PageRepository is a Spring Data repository, so findById(Long), returning an Optional<Page>, is already available, and PageDto.from(Page) maps an entity to the DTO. The existing controller has a list endpoint only:

In DocsAssistant API before the change
package com.example.docsassistant;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class DocsController {

    private final PageRepository pageRepository;

    public DocsController(PageRepository pageRepository) {
        this.pageRepository = pageRepository;
    }

    @GetMapping("/api/pages")
    public List<PageDto> listPages() {
        return pageRepository.findAll().stream().map(PageDto::from).toList();
    }
}
In Claude Code
$ claude "add a GET /api/pages/{id} endpoint to @src/main/java/com/example/docsassistant/DocsController.java
that returns the page as a PageDto using PageRepository.findById, or a 404 with a JSON error body when the id
doesn't exist"

Claude reads the referenced file plus PageRepository and PageDto on its own, proposes the change, and (in Manual or Accept-edits mode) shows this diff before or as it applies it:

 package com.example.docsassistant;

+import org.springframework.http.HttpStatus;
+import org.springframework.http.ProblemDetail;
+import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RestController;

 import java.util.List;

 @RestController
 public class DocsController {

     private final PageRepository pageRepository;

     public DocsController(PageRepository pageRepository) {
         this.pageRepository = pageRepository;
     }

     @GetMapping("/api/pages")
     public List<PageDto> listPages() {
         return pageRepository.findAll().stream().map(PageDto::from).toList();
     }
+
+    @GetMapping("/api/pages/{id}")
+    public ResponseEntity<PageDto> getPage(@PathVariable Long id) {
+        return pageRepository.findById(id)
+                .map(PageDto::from)
+                .map(ResponseEntity::ok)
+                .orElseGet(() -> ResponseEntity.of(ProblemDetail.forStatusAndDetail(
+                        HttpStatus.NOT_FOUND, "No page with id " + id)).build());
+    }
 }

The 404 branch returns a ProblemDetail, which Spring renders as an application/problem+json body. See Spring Framework — Error Responses and Claude Code — Common workflows.

Reviewing this diff before it lands is exactly what Reviewing AI-Generated Code covers in more depth; the immediate follow-up here is asking Claude to run the project’s tests to verify the new endpoint, which is the "verify" part of the agentic loop above.