Project Setup Template for Claude Code
File Structure
For any CLI project that you want Claude Code to build, create these files:
project-name/
├── README.md # User-facing documentation
├── spec.md # Technical specification
├── CLAUDE.md # Instructions for Claude Code
├── prompt.md # The actual prompt to give Claude Code
├── examples/ # Sample inputs/outputs
│ ├── sample_output_1.txt
│ └── sample_output_2.txt
├── reference/ # Any reference materials
│ └── (HTML samples, API docs, etc.)
├── flake.nix # Nix flake (REQUIRED)
└── nix/ # Additional Nix files
├── shell.nix # Development shell
├── package.nix # Package definition (optional, can be in flake.nix)
└── module.nix # NixOS/home-manager module (if applicable)Template: spec.md
# [Project Name] - Technical Specification
## Overview
[1-2 sentence description of what the tool does]
## Command Name
`[command-name]`
## Core Features
1. [Feature 1]
2. [Feature 2]
3. [Feature 3]
## Commands
- `[cmd] <arg>` - [description]
- `[cmd] subcommand <arg>` - [description]
- `[cmd] completion [bash|zsh|fish]` - generate shell completion
## Output Format
[Describe what the output should look like]
- [Color/formatting requirement 1]
- [Color/formatting requirement 2]
- [Wrapping/layout requirement]
## Technical Requirements
### Language & Core Libraries
- Language: [Go/Python/Rust] [version]
- CLI Framework: [cobra/click/clap]
- HTTP Client: [requests/net/http/reqwest]
- HTML/JSON Parser: [specific library]
- Terminal Formatting: [lipgloss/rich/colored]
### Data Source
- API/Website: [URL or description]
- URL Pattern: [example URL structure]
- Data Format: [HTML/JSON/XML]
### Storage/Caching (if applicable)
- Location: `~/.[project-cache]/`
- Format: [JSON/SQLite/plain files]
- Expiry: [duration]
### Error Handling
- [Error type 1]: [how to handle]
- [Error type 2]: [how to handle]
- [Error type 3]: [how to handle]
## Flags
- `--flag1` - [description]
- `--flag2` - [description]
## Example Usage
```bash
$ [command] [args]
[Expected output]
$ [command] --flag [args]
[Expected output with flag]Nix Flake (REQUIRED)
Flake Structure
- Use
nixpkgs.lib.genAttrsorbuiltins.mapAttrsfor multi-platform support - NEVER use flake-utils
- Package definition can be inline or in
./nix/package.nix - Development shell in
./nix/shell.nix - Formatters in
./nix/formatter.nix(if needed) - NixOS/home-manager modules in
./nix/module.nix(if applicable)
Build Requirements
- Use
buildGoModule/buildPythonApplication/buildRustPackage - Pin language version
- Include vendorHash/cargoHash (set to null initially)
- Install completion scripts in postInstall
Supported Platforms
systems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ];Example Flake Pattern
{
description = "[Project description]";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
};
outputs = { self, nixpkgs }:
let
systems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ];
forAllSystems = f: nixpkgs.lib.genAttrs systems (system: f {
pkgs = import nixpkgs { inherit system; };
});
in
{
packages = forAllSystems ({ pkgs }: {
default = pkgs.callPackage ./nix/package.nix { };
# Or define inline if simple
});
devShells = forAllSystems ({ pkgs }: {
default = pkgs.callPackage ./nix/shell.nix { };
});
# Optional: formatter
formatter = forAllSystems ({ pkgs }: pkgs.nixpkgs-fmt);
# Optional: NixOS/home-manager module
nixosModules.default = import ./nix/module.nix;
homeManagerModules.default = import ./nix/module.nix;
};
}Testing Requirements
- Test with [example 1]
- Test with [example 2]
- Test error case [example 3]
- Verify [specific behavior]
---
## Template: CLAUDE.md
```markdown
# Implementation Guide for Claude Code
This document contains implementation details and workflow for Claude Code.
## Implementation Order
### Phase 1: [Core Functionality] (XX min)
1. [Step 1]
2. [Step 2]
3. [Step 3]
4. Test with [examples]
### Phase 2: [Secondary Feature] (XX min)
1. [Step 1]
2. [Step 2]
3. Test [specific behavior]
### Phase 3: [Polish/Packaging] (XX min)
1. [Step 1]
2. [Step 2]
3. Verify [final checks]
## Key Technical Details
### [Data Source] Structure
- Inspect [reference files/URLs]
- Key elements to extract:
- [Element 1]: [selector/pattern]
- [Element 2]: [selector/pattern]
- [Element 3]: [selector/pattern]
### [Important Pattern/Algorithm]
```[language]
// [Description]
[code example or pseudo-code]
Dependencies ([language].mod/requirements.txt/Cargo.toml)
[dependency 1]
[dependency 2]
[dependency 3]
Nix Flake Workflow (REQUIRED)
The project MUST use a Nix flake with the following pattern:
{
description = "[Project description]";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
};
outputs = { self, nixpkgs }:
let
systems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ];
forAllSystems = f: nixpkgs.lib.genAttrs systems (system: f {
pkgs = import nixpkgs { inherit system; };
});
in
{
packages = forAllSystems ({ pkgs }: {
default = # package definition here or pkgs.callPackage ./nix/package.nix { };
});
devShells = forAllSystems ({ pkgs }: {
default = pkgs.callPackage ./nix/shell.nix { };
});
};
}CRITICAL RULES:
- NEVER use flake-utils - always use nixpkgs.lib.genAttrs or builtins.mapAttrs
- Development shell goes in
./nix/shell.nix - Complex package definitions go in
./nix/package.nix - Formatters go in
./nix/formatter.nix - NixOS/home-manager modules go in
./nix/module.nix
Build workflow:
# Step 1: Create flake.nix with vendorHash/cargoHash = null (if applicable)
# Step 2: Try to build
nix build --impure
# This will fail and show: "got: sha256-XXXXX..."
# Step 3: Copy that hash and update flake.nix or ./nix/package.nix
# Step 4: Build successfully
nix build
# Step 5: Test
nix run . -- [test args]Example ./nix/shell.nix:
{ pkgs }:
pkgs.mkShell {
buildInputs = with pkgs; [
# Language-specific tools
go_1_21 # or python3, rustc, etc.
# Development tools
gopls # or python-lsp-server, rust-analyzer, etc.
# Other tools
];
shellHook = ''
echo "[Project Name] development environment"
echo "Run '[build command]' to build"
'';
}Example ./nix/package.nix (Go):
{ lib, buildGoModule }:
buildGoModule {
pname = "[project-name]";
version = "0.1.0";
src = ../.;
vendorHash = null; # Update after first build attempt
ldflags = [ "-s" "-w" ];
postInstall = ''
# Install shell completions
mkdir -p $out/share/bash-completion/completions
mkdir -p $out/share/zsh/site-functions
mkdir -p $out/share/fish/vendor_completions.d
$out/bin/[cmd] completion bash > $out/share/bash-completion/completions/[cmd]
$out/bin/[cmd] completion zsh > $out/share/zsh/site-functions/_[cmd]
$out/bin/[cmd] completion fish > $out/share/fish/vendor_completions.d/[cmd].fish
'';
meta = with lib; {
description = "[Description]";
homepage = "[URL]";
license = licenses.mit;
maintainers = [ ];
mainProgram = "[cmd]";
};
}Shell Completion Implementation (if applicable)
For Cobra (Go):
var completionCmd = &cobra.Command{
Use: "completion [bash|zsh|fish|powershell]",
Short: "Generate completion script",
Long: `[Usage instructions]`,
ValidArgs: []string{"bash", "zsh", "fish", "powershell"},
Args: cobra.ExactValidArgs(1),
Run: func(cmd *cobra.Command, args []string) {
switch args[0] {
case "bash":
cmd.Root().GenBashCompletion(os.Stdout)
case "zsh":
cmd.Root().GenZshCompletion(os.Stdout)
case "fish":
cmd.Root().GenFishCompletion(os.Stdout, true)
case "powershell":
cmd.Root().GenPowerShellCompletionWithDesc(os.Stdout)
}
},
}For Click (Python):
# Use click-completion or click's built-in shell completionFor Clap (Rust):
// Use clap_complete crateTesting Checklist
- [Test case 1]
- [Test case 2]
- [Test case 3]
- [Error handling test 1]
- [Error handling test 2]
- Shell completion generation (all shells)
- Nix flake builds successfully
- Output matches examples/
Common Pitfalls
- [Pitfall 1]: [How to avoid]
- [Pitfall 2]: [How to avoid]
- [Pitfall 3]: [How to avoid]
---
## Template: README.md
```markdown
# [Project Name]
[One-line description of what this tool does]
## Installation
### Using Nix Flakes (Recommended)
```bash
# Try without installing
nix run github:[username]/[project-name] -- [args]
# Install to profile
nix profile install github:[username]/[project-name]
Using [Package Manager]
[install command]From Source
git clone https://github.com/[username]/[project-name]
cd [project-name]
# With Nix
nix build
# Without Nix
[build command]Shell Completion
Bash
source <([command] completion bash)
# Or install permanently:
[command] completion bash | sudo tee /etc/bash_completion.d/[command]Zsh
[command] completion zsh > "${fpath[1]}_[command]"Fish
[command] completion fish > ~/.config/fish/completions/[command].fishUsage
# [Common use case 1]
[command] [args]
# [Common use case 2]
[command] [flags] [args]Examples
See examples/ directory for sample outputs.
Development
With Nix
nix develop
[build command]Without Nix
[setup instructions]
[build command]Project Structure
spec.md- Technical specificationCLAUDE.md- Implementation guide for Claude Codeexamples/- Sample outputsreference/- Reference materialsflake.nix- Nix flake for reproducible builds
License
MIT
---
## Template: prompt.md
```markdown
# Prompt for Claude Code
Create a [language] CLI tool called `[command-name]` for [brief description].
## REQUIREMENTS
### Language & Stack
- [Language] [version]+
- Dependencies:
- [dependency 1] ([purpose])
- [dependency 2] ([purpose])
- [dependency 3] ([purpose])
### Reference Materials
- [Location of reference files]: INSPECT THESE FIRST
- [Description of what's in reference files]
- Extract: [list key data points]
### Core Features
1. Commands:
- `[cmd] <arg>` - [description]
- `[cmd] subcommand <arg>` - [description]
- `[cmd] completion [bash|zsh|fish|powershell]` - generate completion
2. [Feature category 2]:
- [Specific requirement]
- [Specific requirement]
3. Flags:
- `--flag1` - [description]
- `--flag2` - [description]
4. Output Format (see examples/ for exact format):
- [Formatting requirement 1]
- [Formatting requirement 2]
- [Layout/wrapping requirement]
5. [Storage/Caching] (if applicable):
- Location: [path]
- Format: [format description]
- Expiry: [duration]
6. Error Handling:
- [Error type]: "[error message]"
- [Error type]: "[error message]"
7. Nix Flake (REQUIRED):
- Use nixpkgs.lib.genAttrs pattern (NEVER flake-utils)
- Set [vendorHash/cargoHash] = null initially in ./nix/package.nix
- Development shell in ./nix/shell.nix
- Add postInstall to generate completions:
- bash: $out/share/bash-completion/completions/[cmd]
- zsh: $out/share/zsh/site-functions/_[cmd]
- fish: $out/share/fish/vendor_completions.d/[cmd].fish
- Support systems: x86_64-linux, aarch64-linux, x86_64-darwin, aarch64-darwin
### [Important Pattern/Algorithm]
```[language]
[code example or pattern to follow]
IMPLEMENTATION ORDER
- Inspect [reference materials]
- Set up [language] module/package with dependencies
- [Core functionality step]
- [Core functionality step]
- Add completion command using [framework]‘s built-in generators
- Implement [formatting/display]
- [Additional feature]
- Create Nix flake structure:
- flake.nix with nixpkgs.lib.genAttrs pattern (NO flake-utils)
- ./nix/package.nix with [hash] = null
- ./nix/shell.nix with dev tools
- Run ‘nix build —impure’ to get [hash], update ./nix/package.nix
- Test thoroughly
Nix Flake Workflow (REQUIRED)
CRITICAL: Use nixpkgs.lib.genAttrs, NEVER flake-utils
flake.nix pattern:
{
description = "[description]";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
outputs = { self, nixpkgs }:
let
systems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ];
forAllSystems = f: nixpkgs.lib.genAttrs systems (system: f {
pkgs = import nixpkgs { inherit system; };
});
in
{
packages = forAllSystems ({ pkgs }: {
default = pkgs.callPackage ./nix/package.nix { };
});
devShells = forAllSystems ({ pkgs }: {
default = pkgs.callPackage ./nix/shell.nix { };
});
};
}Build workflow:
# Create ./nix/package.nix with [hash] = null
nix build --impure
# Copy hash from error and update ./nix/package.nix
nix build
nix run . -- [test args]
nix develop./nix/shell.nix example:
{ pkgs }:
pkgs.mkShell {
buildInputs = with pkgs; [
[language-tools]
];
shellHook = ''
echo "[Project] dev environment"
'';
}./nix/package.nix example:
{ lib, [buildFunction] }:
[buildFunction] {
pname = "[name]";
version = "0.1.0";
src = ../.;
[vendorHash/cargoHash] = null; # Update after build
postInstall = ''
# Install completions
mkdir -p $out/share/{bash-completion/completions,zsh/site-functions,fish/vendor_completions.d}
$out/bin/[cmd] completion bash > $out/share/bash-completion/completions/[cmd]
$out/bin/[cmd] completion zsh > $out/share/zsh/site-functions/_[cmd]
$out/bin/[cmd] completion fish > $out/share/fish/vendor_completions.d/[cmd].fish
'';
meta = with lib; {
description = "[description]";
license = licenses.mit;
mainProgram = "[cmd]";
};
}Completion Command Example
[code example for completion command]TESTING
Test with:
- [Test case 1]
- [Test case 2]
- [Test case 3]
- [Error case]
Test completions:
./[cmd] completion bash > /tmp/test.bash
source /tmp/test.bash
# Try: [cmd] [partial]<TAB>Test Nix:
nix flake check
nix build
nix run . -- [args]Verify:
- Output matches examples/
- [Specific behavior works]
- [Specific behavior works]
- Completions work in all shells
- Nix flake builds successfully
START BY
- Reading [reference materials]
- Creating [language] module with dependencies
- [First implementation step]
- [Second implementation step]
- Testing thoroughly
Reference spec.md and CLAUDE.md for complete details.
---
## How to Use This Template
1. **Create project directory** with the file structure above
2. **Create nix/ directory** for Nix-related files
3. **Fill in spec.md** with your project's specific requirements
4. **Fill in CLAUDE.md** with implementation details and technical patterns
5. **Fill in README.md** with user-facing documentation
6. **Fill in prompt.md** - this is what you paste into Claude Code
7. **Add examples/** with expected outputs
8. **Add reference/** with any HTML samples, API docs, etc.
The key is:
- **spec.md** = WHAT to build (requirements)
- **CLAUDE.md** = HOW to build it (implementation guide)
- **README.md** = User documentation
- **prompt.md** = The actual prompt (combines key parts of spec + CLAUDE)
- **examples/** = Concrete examples of expected behavior
- **reference/** = Source materials to parse/scrape
- **flake.nix** = Nix flake using nixpkgs.lib.genAttrs (NEVER flake-utils)
- **nix/** = Additional Nix files (shell.nix, package.nix, etc.)
**Critical Nix Rules:**
- Always use nixpkgs.lib.genAttrs or builtins.mapAttrs for multi-system support
- NEVER use flake-utils
- Put development shell in `./nix/shell.nix`
- Put package definition in `./nix/package.nix` (if complex) or inline in flake.nix
- Put formatters in `./nix/formatter.nix`
- Put modules in `./nix/module.nix`
This structure is reusable for any CLI project!