
Project Setup
- 44 installs
- 49 repo stars
- Updated February 11, 2026
- ratacat/claude-skills
Helps with ai & agent building tasks.
About
project-setup is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- project-setup
- AI & Agent Building
- AI-coding skill
Project Setup by the numbers
- 44 all-time installs (skills.sh)
- Ranked #7,757 of 16,556 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Jul 28, 2026 (Skillselion catalog sync)
npx skills add https://github.com/ratacat/claude-skills --skill project-setupAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 44 |
|---|---|
| repo stars | ★ 49 |
| Last updated | February 11, 2026 |
| Repository | ratacat/claude-skills ↗ |
What it does
Helps with ai & agent building tasks.
Files
Project Setup
Core Principles
- Strong Typing: Strict mode enabled; types catch bugs at compile time
- Strong Linting: Strict rules by default; easier to disable than add later
- Auto Formatting: Automated and consistent; no manual formatting
- Checks at Every Stage: Pre-commit hooks + CI; catch issues early
- Co-located Tests:
foo.ts→foo.test.ts; obvious what's tested - Behavior-Focused: Test what code does, not how; mock only external boundaries
Workflow
1. Check reference/ for language guide (Python, TypeScript) 2. If no guide: WebSearch "[language] project setup best practices" 3. Follow setup: typing → linting → formatting → testing → pre-commit → CI 4. For existing projects: migrate incrementally in same order
Reference Files
reference/python.md- uv, ruff, basedpyright, pytestreference/typescript.md- pnpm, ESLint, Prettier, Vitestreference/common-patterns.md- Testing philosophy, CI patterns, security
Tool Selection
Prefer tools that are: ecosystem standard, actively maintained, strict by default, fast, well-integrated (editor + CI + pre-commit).
Quality Checklist
- [ ] Typing: Strictest mode, no
anywithout justification - [ ] Linting: Strict rules, warnings as errors
- [ ] Formatting: Auto-format on save + pre-commit
- [ ] Testing: Co-located tests, coverage >80%
- [ ] Pre-commit: Format, lint, type-check
- [ ] CI: Same checks + coverage reporting
- [ ] README: Setup instructions
- [ ] All checks pass on initial commit
Common Patterns Across Languages
Language-specific configs (.gitignore, .editorconfig, CI, security) are in language reference files.
Git Principles
Universal .gitignore entries:
.idea/
.vscode/
*.swp
.DS_Store
.env
.env.local
*.logUniversal .editorconfig:
root = true
[*]
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
charset = utf-8
[*.md]
trim_trailing_whitespace = falseREADME Essentials
Every README needs: description, quick start (install + test), prerequisites, commands table, project structure.
Pre-commit Order
1. Format (fast, auto-fixable) 2. Lint (fast, static analysis) 3. Type check (medium) 4. Tests (slow)
Use incremental tools: lint-staged (JS/TS), pre-commit (Python).
CI Order
Same as pre-commit: format → lint → typecheck → test. Fast feedback on simple issues first.
Testing Philosophy
Test types:
| Type | What | When |
|---|---|---|
| Unit | Pure functions, business logic | Always |
| Integration | Database, API endpoints | Critical paths |
| E2E | User journeys | Happy paths only |
Mocking rules:
- Mock at boundaries: HTTP, filesystem, time, random, third-party APIs
- Don't mock: your own code, database in integration tests
Structure: Arrange → Act → Assert
Environment Variables
.env # Defaults (committed)
.env.local # Local overrides (gitignored)Never commit secrets. Use os.environ["KEY"] or GitHub Secrets.
Documentation
- README: Setup, usage, contribution
- Code comments: Why, not what
- Types: Shape of data, constraints
- Tests: Expected behavior
Versioning
Semantic: MAJOR.MINOR.PATCH (breaking.feature.fix)
Dependencies
Update order: dev deps → patch → minor → major (with testing).
Always commit lock files for reproducible builds.
Security
- Enable Dependabot/Renovate for automated updates
- Run security audits in CI
- Never commit secrets; rotate if exposed
Python Project Setup
Tool Stack (December 2025)
| Purpose | Tool | Version |
|---|---|---|
| Runtime | Python | 3.14 |
| Package manager | uv | 0.9.15 |
| Linting/Formatting | ruff | 0.14.8 |
| Type checking | basedpyright | 1.35.0 |
| Testing | pytest | 9.0.1 |
| Coverage | pytest-cov | 7.0.0 |
| Pre-commit | pre-commit | 4.5.0 |
Project Structure
my-project/
├── pyproject.toml
├── .python-version
├── .pre-commit-config.yaml
├── src/my_project/
│ ├── __init__.py
│ ├── core.py
│ └── core_test.py # Co-located tests
└── tests/integration/ # Integration tests onlySetup
curl -LsSf https://astral.sh/uv/install.sh | sh
uv init my-project && cd my-project
echo "3.14" > .python-version
mkdir -p src/my_project tests/integration
touch src/my_project/__init__.pypyproject.toml
[project]
name = "my-project"
version = "0.1.0"
requires-python = ">=3.14"
dependencies = []
[project.optional-dependencies]
dev = ["basedpyright>=1.35.0", "pytest>=9.0.1", "pytest-cov>=7.0.0", "pre-commit>=4.5.0"]
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.build.targets.wheel]
packages = ["src/my_project"]
[tool.ruff]
line-length = 120
target-version = "py314"
src = ["src", "tests"]
[tool.ruff.lint]
select = ["F", "E", "W", "C4", "B", "I", "UP", "ARG", "SIM", "TCH", "PTH", "ERA", "PL", "RUF"]
ignore = ["E501", "PLR0913", "PLR2004"]
[tool.ruff.lint.per-file-ignores]
"*_test.py" = ["ARG001"]
"tests/**" = ["ARG001"]
[tool.ruff.lint.isort]
known-first-party = ["my_project"]
[tool.basedpyright]
pythonVersion = "3.14"
typeCheckingMode = "all"
reportMissingTypeStubs = "warning"
reportUnusedImport = "error"
reportUnusedVariable = "error"
reportOptionalMemberAccess = "error"
reportOptionalSubscript = "error"
reportOptionalCall = "error"
[tool.pytest.ini_options]
testpaths = ["src", "tests"]
python_files = ["*_test.py", "test_*.py"]
addopts = ["--import-mode=importlib", "-ra", "--strict-markers", "--strict-config"]
filterwarnings = ["error"]
strict = true
[tool.coverage.run]
source = ["src"]
branch = true
omit = ["*_test.py"]
[tool.coverage.report]
exclude_lines = ["pragma: no cover", "if TYPE_CHECKING:", "raise NotImplementedError"]
fail_under = 80
show_missing = true.pre-commit-config.yaml
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.14.8
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
- id: ruff-format
- repo: local
hooks:
- id: basedpyright
name: basedpyright
entry: uv run basedpyright
language: system
types: [python]
pass_filenames: false
- id: pytest
name: pytest
entry: uv run pytest
language: system
pass_filenames: false
always_run: trueuv sync --all-extras && uv run pre-commit installCommands
uv run pytest # Run tests
uv run pytest --cov # With coverage
uv run ruff check . --fix # Lint + fix
uv run ruff format . # Format
uv run basedpyright # Type check
uv pip list --outdated # Check updates
uv lock --upgrade # Update depsGitHub Actions CI
.github/workflows/ci.yml:
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v4
with:
enable-cache: true
cache-dependency-glob: 'uv.lock'
- run: uv python install
- run: uv sync --all-extras
- run: uv run ruff format --check .
- run: uv run ruff check .
- run: uv run basedpyright
- run: uv run pytest --cov --cov-report=xml
- uses: codecov/codecov-action@v4
with:
files: coverage.xmlTest Example
# src/my_project/calculator.py
def add(a: int, b: int) -> int:
return a + b
# src/my_project/calculator_test.py
from my_project.calculator import add
def test_add() -> None:
assert add(2, 3) == 5
assert add(-1, -1) == -2.gitignore
__pycache__/
*.py[cod]
.venv/
.basedpyright/
.pytest_cache/
.coverage
coverage.xml
.ruff_cache/
dist/
*.egg-info/
.env
.env.local.editorconfig
[*.py]
indent_style = space
indent_size = 4
max_line_length = 120Security & Dependabot
uv add --dev pip-audit && uv run pip-audit.github/dependabot.yml:
version: 2
updates:
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "weekly"TypeScript Project Setup
Tool Stack (December 2025)
| Purpose | Tool | Version |
|---|---|---|
| Runtime | Node.js | 24 (LTS) |
| Package manager | pnpm | 9.x |
| Type checking | TypeScript | 5.9.3 |
| Linting | ESLint + typescript-eslint | 9.39.1 / 8.48.1 |
| Formatting | Prettier | 3.7.4 |
| Testing | Vitest | 4.0.15 |
| Pre-commit | Husky + lint-staged | 9.1.7 / 16.2.7 |
Project Structure
my-project/
├── package.json
├── tsconfig.json
├── eslint.config.ts
├── .prettierrc
├── vitest.config.ts
├── .husky/pre-commit
└── src/
├── index.ts
├── core.ts
└── core.test.ts # Co-located testsSetup
mkdir my-project && cd my-project
pnpm init
pnpm add -D typescript @types/node
pnpm tsc --init
mkdir src && touch src/index.tstsconfig.json
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noFallthroughCasesInSwitch": true,
"exactOptionalPropertyTypes": true,
"noImplicitReturns": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"module": "NodeNext",
"moduleResolution": "NodeNext",
"verbatimModuleSyntax": true,
"target": "ES2024",
"outDir": "dist",
"declaration": true,
"sourceMap": true,
"lib": ["ES2024"],
"types": ["node", "vitest/globals"],
"skipLibCheck": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}ESLint
pnpm add -D eslint @eslint/js typescript-eslint globals eslint-config-prettiereslint.config.ts:
import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';
import globals from 'globals';
import prettierConfig from 'eslint-config-prettier';
export default tseslint.config(
{ ignores: ['dist/**', 'node_modules/**', 'coverage/**'] },
eslint.configs.recommended,
tseslint.configs.strictTypeChecked,
tseslint.configs.stylisticTypeChecked,
{
languageOptions: {
globals: { ...globals.node },
parserOptions: { projectService: true, tsconfigRootDir: import.meta.dirname },
},
},
{
rules: {
'@typescript-eslint/explicit-function-return-type': 'error',
'@typescript-eslint/no-explicit-any': 'error',
'@typescript-eslint/no-floating-promises': 'error',
'@typescript-eslint/no-misused-promises': 'error',
'@typescript-eslint/consistent-type-imports': ['error', { prefer: 'type-imports', fixStyle: 'inline-type-imports' }],
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
},
},
{ files: ['**/*.test.ts'], rules: { '@typescript-eslint/explicit-function-return-type': 'off' } },
{ files: ['**/*.js', '**/*.mjs'], ...tseslint.configs.disableTypeChecked },
prettierConfig,
);Prettier
.prettierrc:
{ "semi": true, "singleQuote": true, "tabWidth": 2, "printWidth": 120 }Vitest
pnpm add -D vitest @vitest/coverage-v8vitest.config.ts:
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
globals: true,
include: ['src/**/*.test.ts'],
coverage: {
provider: 'v8',
include: ['src/**/*.ts'],
exclude: ['src/**/*.test.ts'],
thresholds: { statements: 80, branches: 75, functions: 80, lines: 80 },
},
},
});Pre-commit
pnpm add -D husky lint-staged
pnpm exec husky init
echo "pnpm lint-staged" > .husky/pre-commitpackage.json
{
"type": "module",
"scripts": {
"build": "tsc",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"format": "prettier --write .",
"format:check": "prettier --check .",
"typecheck": "tsc --noEmit",
"test": "vitest",
"test:coverage": "vitest run --coverage",
"check": "pnpm typecheck && pnpm lint && pnpm format:check && pnpm test",
"prepare": "husky"
},
"lint-staged": {
"*.{ts,tsx}": ["eslint --fix", "prettier --write"],
"*.{json,md,yml,yaml}": ["prettier --write"]
}
}GitHub Actions CI
.github/workflows/ci.yml:
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: '24'
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- run: pnpm format:check
- run: pnpm lint
- run: pnpm typecheck
- run: pnpm test:coverage
- uses: codecov/codecov-action@v4
with:
files: coverage/lcov.infoTest Example
// src/calculator.ts
export function add(a: number, b: number): number {
return a + b;
}
// src/calculator.test.ts
import { describe, it, expect } from 'vitest';
import { add } from './calculator.js';
describe('add', () => {
it('adds numbers', () => {
expect(add(2, 3)).toBe(5);
expect(add(-1, -1)).toBe(-2);
});
});.gitignore
node_modules/
dist/
coverage/
*.tsbuildinfo
.env
.env.local.editorconfig
[*.{ts,tsx,js,jsx,json,yml,yaml}]
indent_style = space
indent_size = 2
max_line_length = 120Security & Dependabot
pnpm audit.github/dependabot.yml:
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"