Skip to content

Instantly share code, notes, and snippets.

@alessandroamella
Last active June 2, 2025 12:53
Show Gist options
  • Save alessandroamella/5a64da16cebd0a52ad744a26a81575b0 to your computer and use it in GitHub Desktop.
Save alessandroamella/5a64da16cebd0a52ad744a26a81575b0 to your computer and use it in GitHub Desktop.
TypeScript starter (pnpm, TypeScript, Husky, Biome)
#!/bin/bash
# TypeScript Starter Project Initialization Script
set -e
# Check if path parameter is provided
if [ $# -ne 1 ]; then
echo "Usage: $0 <project-path>"
echo "Example: $0 ./my-project"
exit 1
fi
PROJECT_PATH="$1"
# Create project directory and change to it
echo "πŸ“ Creating project directory: $PROJECT_PATH"
mkdir -p "$PROJECT_PATH"
cd "$PROJECT_PATH"
echo "πŸš€ Initializing TypeScript starter project in $(pwd)..."
# Initialize package.json
echo "πŸ“¦ Initializing package.json..."
pnpm init
# Install dev dependencies
echo "πŸ“š Installing dev dependencies..."
pnpm --allow-build=@biomejs/biome -D add @biomejs/biome @types/node husky ts-node typescript @types/dotenv-safe
# Install regular dependencies
echo "πŸ“¦ Installing dependencies..."
pnpm add dotenv-safe
# Initialize Git repository
echo "🎯 Initializing Git repository..."
git init
# Initialize Biome
echo "🌿 Creating Biome configuration..."
cat >biome.json <<'EOL'
{
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
"vcs": {
"enabled": false,
"clientKind": "git",
"useIgnoreFile": false
},
"files": {
"ignoreUnknown": false
},
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2
},
"organizeImports": {
"enabled": true
},
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"a11y": {
"useSemanticElements": "off"
},
"correctness": {
"noUnusedFunctionParameters": "error",
"noUnusedVariables": "warn",
"noUnusedImports": "error",
"noUnusedPrivateClassMembers": "warn",
"noUnusedLabels": "error"
},
"style": {
"noNonNullAssertion": "off"
},
"nursery": {
"noCommonJs": "error",
"noDuplicateElseIf": "error",
"noDuplicateProperties": "error",
"noSubstr": "error",
"noEnum": "off",
"noIrregularWhitespace": "error"
}
}
},
"javascript": {
"formatter": {
"quoteStyle": "single",
"jsxQuoteStyle": "single"
}
}
}
EOL
# Create tsconfig.json
echo "βš™οΈ Creating tsconfig.json..."
cat >tsconfig.json <<'EOL'
{
"compilerOptions": {
"target": "ES2022",
"module": "commonjs",
"lib": ["ES2022"],
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"removeComments": true,
"noImplicitAny": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noUnusedLocals": true,
"noUnusedParameters": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
EOL
# Create src directory and index.ts
echo "πŸ“ Creating src directory and index.ts..."
mkdir -p src
cat >src/index.ts <<'EOL'
function main(): void {
console.log("Hello, World! 🌍");
console.log("Welcome to your TypeScript starter project!");
}
main();
EOL
# Create .vscode directory and configuration files
echo "πŸ“ Creating .vscode directory and configuration files..."
mkdir -p .vscode
cat >.vscode/extensions.json <<'EOL'
{
"recommendations": ["biomejs.biome"]
}
EOL
cat >.vscode/settings.json <<'EOL'
{
"[typescript]": {
"editor.defaultFormatter": "biomejs.biome"
},
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports.biome": "explicit",
"source.fixAll.biome": "explicit",
"source.organizeImports": "never",
"source.fixAll": "never"
}
}
EOL
# Add scripts to package.json
echo "πŸ“ Adding scripts to package.json..."
# Use node to modify package.json and add the lint script
node -e "
const fs = require('fs');
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
pkg.scripts = {
lint: 'biome check --write ./src',
dev: 'ts-node src/index.ts',
build: 'tsc',
start: 'node dist/index.js'
};
fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2));
"
# Initialize Husky
echo "πŸ• Initializing Husky..."
pnpm exec husky init
# Set up pre-commit hook
echo "πŸͺ Setting up pre-commit hook..."
cat >.husky/pre-commit <<'EOL'
pnpm lint
EOL
chmod +x .husky/pre-commit
# Create .gitignore
echo "🚫 Creating .gitignore..."
cat >.gitignore <<'EOL'
# Dependencies
node_modules/
.pnpm-store/
# Build output
dist/
build/
# TypeScript
*.tsbuildinfo
# Environment variables
.env
.env.local
.env.*.local
# IDE
.vscode/
.idea/
*.swp
*.swo
# OS
.DS_Store
Thumbs.db
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
EOL
# Create .env.example
echo "πŸ“ Creating .env.example..."
cat >.env.example <<'EOL'
NODE_ENV=development
EOL
echo "βœ… TypeScript starter project initialized successfully!"
echo ""
echo "🎨 Running initial lint to format created files..."
pnpm lint
echo ""
echo "πŸ“‹ Available scripts:"
echo " pnpm dev - Run development server with ts-node"
echo " pnpm build - Build the project"
echo " pnpm start - Run the built project"
echo " pnpm lint - Lint and format code with Biome"
echo ""
echo "🎯 Try running: pnpm dev"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment