Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@ To use this feature in your devcontainer, add it to your `devcontainer.json` fil
}
```

## Requirements

The feature automatically depends on Node.js and will install it if not already present.

## Building and Testing

You can build and test the feature using the [dev container CLI](https://github.com/devcontainers/cli):
Expand All @@ -35,4 +31,4 @@ devcontainer feature publish -n anthropics/devcontainer-features .

## License

This project is licensed under the MIT License - see the LICENSE file for details.
This project is licensed under the MIT License - see the LICENSE file for details.
30 changes: 6 additions & 24 deletions src/claude-code/NOTES.md
Original file line number Diff line number Diff line change
@@ -1,37 +1,19 @@
# Using Claude Code in devcontainers

## Requirements
## Installation

This feature requires Node.js and npm to be available in the container. You need to either:

1. Use a base container image that includes Node.js, or
2. Add the Node.js feature to your devcontainer.json
3. Let this feature attempt to install Node.js automatically (best-effort, works on Debian/Ubuntu, Alpine, Fedora, RHEL, and CentOS)

Note: When auto-installing Node.js, a compatible LTS version (Node.js 18.x) will be used.

## Recommended configuration

For most setups, we recommend explicitly adding both features:
This feature installs Claude Code using the [native installer](https://claude.ai/install.sh). No additional features or dependencies need to be added to your devcontainer configuration.

```json
"features": {
"ghcr.io/devcontainers/features/node:1": {},
"ghcr.io/anthropics/devcontainer-features/claude-code:1": {}
}
```

## Using with containers that already have Node.js

If your container already has Node.js installed (for example, a container based on a Node.js image or one using nvm), you can use the Claude Code feature directly without adding the Node.js feature:

```json
"features": {
"ghcr.io/anthropics/devcontainer-features/claude-code:1": {}
}
```
## Alpine Linux

## Using with nvm
On Alpine-based containers, this feature automatically installs the required additional dependencies: `libgcc`, `libstdc++`, and `ripgrep`.

When using with containers that have nvm pre-installed, you can use the Claude Code feature directly, and it will use the existing Node.js installation.
## Deprecation notice

The previous NPM-based installation method (`npm install -g @anthropic-ai/claude-code`) has been deprecated. This feature now uses the native installer. For more information, see the [official documentation](https://code.claude.com/docs/en/getting-started#npm-installation-deprecated).
8 changes: 2 additions & 6 deletions src/claude-code/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

# Claude Code CLI (claude-code)

Installs the Claude Code CLI globally
Expand All @@ -14,8 +13,7 @@ Installs the Claude Code CLI globally
## Options

| Options Id | Description | Type | Default Value |
|-----|-----|-----|-----|

| ---------- | ----------- | ---- | ------------- |

## Customizations

Expand Down Expand Up @@ -60,8 +58,6 @@ If your container already has Node.js installed (for example, a container based

When using with containers that have nvm pre-installed, you can use the Claude Code feature directly, and it will use the existing Node.js installation.



---

_Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/anthropics/devcontainer-features/blob/main/src/claude-code/devcontainer-feature.json). Add additional notes to a `NOTES.md`._
_Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/anthropics/devcontainer-features/blob/main/src/claude-code/devcontainer-feature.json). Add additional notes to a `NOTES.md`._
29 changes: 12 additions & 17 deletions src/claude-code/devcontainer-feature.json
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
{
"name": "Claude Code CLI",
"id": "claude-code",
"version": "1.0.5",
"description": "Installs the Claude Code CLI globally",
"options": {},
"documentationURL": "https://github.com/anthropics/devcontainer-features/tree/main/src/claude-code",
"licenseURL": "https://github.com/anthropics/devcontainer-features/blob/main/LICENSE",
"customizations": {
"vscode": {
"extensions": [
"anthropic.claude-code"
]
}
},
"installsAfter": [
"ghcr.io/devcontainers/features/node"
]
"name": "Claude Code CLI",
"id": "claude-code",
"version": "1.0.6",
"description": "Installs the Claude Code CLI globally",
"options": {},
"documentationURL": "https://github.com/anthropics/devcontainer-features/tree/main/src/claude-code",
"licenseURL": "https://github.com/anthropics/devcontainer-features/blob/main/LICENSE",
"customizations": {
"vscode": {
"extensions": ["anthropic.claude-code"]
}
}
}
99 changes: 27 additions & 72 deletions src/claude-code/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ install_packages() {
local pkg_manager="$1"
shift
local packages="$@"

case "$pkg_manager" in
apt)
apt-get update
Expand All @@ -38,86 +38,32 @@ install_packages() {
return 1
;;
esac

return 0
}

# Function to install Node.js
install_nodejs() {
local pkg_manager="$1"

echo "Installing Node.js using $pkg_manager..."

case "$pkg_manager" in
apt)
# Debian/Ubuntu - install more recent Node.js LTS
install_packages apt "ca-certificates curl gnupg"
mkdir -p /etc/apt/keyrings
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list
apt-get update
apt-get install -y nodejs
;;
apk)
# Alpine
install_packages apk "nodejs npm"
;;
dnf)
# Fedora/RHEL
install_packages dnf "nodejs npm"
;;
yum)
# CentOS/RHEL
curl -sL https://rpm.nodesource.com/setup_18.x | bash -
yum install -y nodejs
;;
*)
echo "ERROR: Unsupported package manager for Node.js installation"
return 1
;;
esac

# Verify installation
if command -v node >/dev/null && command -v npm >/dev/null; then
echo "Successfully installed Node.js and npm"
return 0
else
echo "Failed to install Node.js and npm"
return 1
fi
return 0
}

# Function to install Claude Code CLI
# Function to install Claude Code CLI using the native installer
install_claude_code() {
echo "Installing Claude Code CLI..."
npm install -g @anthropic-ai/claude-code
su - "$_REMOTE_USER" -c 'curl -fsSL https://claude.ai/install.sh | bash'

if command -v claude >/dev/null; then
# The native installer places the binary in ~/.local/bin (symlink to ~/.local/share/claude/).
# Copy the resolved binary to /usr/local/bin so it is available to all users.
REMOTE_USER_HOME=$(eval echo "~$_REMOTE_USER")
CLAUDE_LOCAL="$REMOTE_USER_HOME/.local/bin/claude"
if [ -e "$CLAUDE_LOCAL" ]; then
CLAUDE_REAL="$(readlink -f "$CLAUDE_LOCAL")"
cp "$CLAUDE_REAL" /usr/local/bin/claude
chmod +x /usr/local/bin/claude
echo "Claude Code CLI installed successfully!"
claude --version
/usr/local/bin/claude --version
return 0
else
echo "ERROR: Claude Code CLI installation failed!"
return 1
fi
}

# Print error message about requiring Node.js feature
print_nodejs_requirement() {
cat <<EOF

ERROR: Node.js and npm are required but could not be installed!
Please add the Node.js feature to your devcontainer.json:

"features": {
"ghcr.io/devcontainers/features/node:1": {},
"ghcr.io/anthropics/devcontainer-features/claude-code:1": {}
}

EOF
exit 1
}

# Main script starts here
main() {
echo "Activating feature 'claude-code'"
Expand All @@ -126,15 +72,24 @@ main() {
PKG_MANAGER=$(detect_package_manager)
echo "Detected package manager: $PKG_MANAGER"

# Try to install Node.js if it's not available
if ! command -v node >/dev/null || ! command -v npm >/dev/null; then
echo "Node.js or npm not found, attempting to install automatically..."
install_nodejs "$PKG_MANAGER" || print_nodejs_requirement
# Ensure curl and bash are available
MISSING_DEPS=""
command -v curl >/dev/null || MISSING_DEPS="$MISSING_DEPS curl"
command -v bash >/dev/null || MISSING_DEPS="$MISSING_DEPS bash"
if [ -n "$MISSING_DEPS" ]; then
echo "Installing missing dependencies:$MISSING_DEPS"
install_packages "$PKG_MANAGER" $MISSING_DEPS
fi

# Alpine requires additional dependencies for the native installer
if [ "$PKG_MANAGER" = "apk" ]; then
echo "Alpine detected, installing additional dependencies..."
install_packages apk libgcc libstdc++ ripgrep
fi

# Install Claude Code CLI
install_claude_code || exit 1
}

# Execute main function
main
main
3 changes: 1 addition & 2 deletions test/claude-code/scenarios.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
"basic": {
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
"features": {
"ghcr.io/devcontainers/features/node:1": {},
"claude-code": {}
}
}
}
}
4 changes: 1 addition & 3 deletions test/claude-code/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@ set -e
source dev-container-features-test-lib

# Feature-specific tests
check "node version" node --version
check "npm version" npm --version
check "claude cli installed" command -v claude
check "claude version" claude --version

# Report results
reportResults
reportResults