Complete TypeScript Project Setup Guide
A step-by-step guide to setting up a modern TypeScript project with best practices for developer experience.
Complete TypeScript Project Setup Guide
Setting up a TypeScript project correctly from the start can save you hours of debugging and configuration headaches later. This guide walks you through creating a modern TypeScript project with optimal developer experience.
Prerequisites
- Node.js 18+ installed
- A code editor (VS Code recommended)
- Basic familiarity with TypeScript
Step 1: Project Initialization
Create the project structure
mkdir my-typescript-project
cd my-typescript-project
npm init -y
Install TypeScript and essential dependencies
npm install typescript @types/node --save-dev
npm install ts-node nodemon --save-dev
Step 2: TypeScript Configuration
Create tsconfig.json
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"noEmit": true,
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"allowJs": true,
"incremental": true,
"tsBuildInfoFile": ".tsbuildinfo",
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.spec.ts"]
}
Key configuration explanations
strict: true
: Enables all strict type checking optionsnoUncheckedIndexedAccess
: Adds undefined to index signaturesexactOptionalPropertyTypes
: More precise optional property handlingincremental: true
: Enables faster rebuildspaths
: Enables clean imports with@/
prefix
Step 3: Development Environment Setup
VS Code Configuration
Create .vscode/settings.json
:
{
"typescript.preferences.includePackageJsonAutoImports": "off",
"typescript.suggest.autoImports": true,
"typescript.updateImportsOnFileMove.enabled": "always",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit",
"source.organizeImports": "explicit"
},
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
Install ESLint and Prettier
npm install eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin --save-dev
npm install prettier eslint-config-prettier eslint-plugin-prettier --save-dev
ESLint Configuration
Create .eslintrc.js
:
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 2022,
sourceType: 'module',
},
plugins: ['@typescript-eslint'],
extends: [
'eslint:recommended',
'@typescript-eslint/recommended',
'prettier',
],
rules: {
'@typescript-eslint/no-unused-vars': 'error',
'@typescript-eslint/no-explicit-any': 'warn',
'@typescript-eslint/prefer-const': 'error',
'@typescript-eslint/no-var-requires': 'error',
},
};
Prettier Configuration
Create .prettierrc
:
{
"semi": true,
"trailingComma": "es5",
"singleQuote": true,
"printWidth": 80,
"tabWidth": 2,
"useTabs": false
}
Step 4: Build and Development Tools
Package.json Scripts
Update your package.json
:
{
"scripts": {
"dev": "tsx watch src/index.ts",
"build": "tsc",
"start": "node dist/index.js",
"lint": "eslint src --ext .ts",
"lint:fix": "eslint src --ext .ts --fix",
"format": "prettier --write src/**/*.ts",
"type-check": "tsc --noEmit"
}
}
Install tsx for development
npm install tsx --save-dev
Step 5: Project Structure
Create this folder structure:
src/
├── index.ts
├── types/
│ └── index.ts
├── utils/
│ └── index.ts
├── services/
│ └── index.ts
└── config/
└── index.ts
Example index.ts
import { config } from './config';
import { logger } from './utils/logger';
async function main() {
try {
logger.info('Starting application...');
// Your application logic here
logger.info('Application started successfully');
} catch (error) {
logger.error('Failed to start application:', error);
process.exit(1);
}
}
main();
Step 6: Environment Configuration
Install dotenv
npm install dotenv
Create environment files
.env.example
:
NODE_ENV=development
PORT=3000
DATABASE_URL=postgresql://localhost:5432/myapp
API_KEY=your-api-key-here
.env
:
NODE_ENV=development
PORT=3000
DATABASE_URL=postgresql://localhost:5432/myapp
API_KEY=your-actual-api-key
Environment configuration
Create src/config/index.ts
:
import dotenv from 'dotenv';
dotenv.config();
export const config = {
nodeEnv: process.env.NODE_ENV || 'development',
port: parseInt(process.env.PORT || '3000', 10),
databaseUrl: process.env.DATABASE_URL,
apiKey: process.env.API_KEY,
} as const;
// Type-safe config access
export type Config = typeof config;
Step 7: Testing Setup
Install testing dependencies
npm install vitest @vitest/ui --save-dev
npm install @types/jest --save-dev
Vitest Configuration
Create vitest.config.ts
:
import { defineConfig } from 'vitest/config';
import { resolve } from 'path';
export default defineConfig({
test: {
globals: true,
environment: 'node',
},
resolve: {
alias: {
'@': resolve(__dirname, './src'),
},
},
});
Add test script
Update package.json
:
{
"scripts": {
"test": "vitest",
"test:ui": "vitest --ui",
"test:coverage": "vitest --coverage"
}
}
Step 8: Git Configuration
.gitignore
Create .gitignore
:
# Dependencies
node_modules/
# Build outputs
dist/
build/
# Environment files
.env
.env.local
.env.*.local
# IDE files
.vscode/
.idea/
# OS files
.DS_Store
Thumbs.db
# Logs
*.log
npm-debug.log*
# TypeScript build info
.tsbuildinfo
# Test coverage
coverage/
# Temporary files
*.tmp
*.temp
Git hooks (optional)
Install husky for git hooks:
npm install husky lint-staged --save-dev
npx husky install
npx husky add .husky/pre-commit "npx lint-staged"
Create .lintstagedrc.js
:
module.exports = {
'*.ts': ['eslint --fix', 'prettier --write'],
'*.js': ['eslint --fix', 'prettier --write'],
'*.json': ['prettier --write'],
};
Step 9: Documentation
README.md
Create a comprehensive README:
# My TypeScript Project
A modern TypeScript project with optimal developer experience.
## Getting Started
1. Install dependencies:
```bash
npm install
-
Set up environment variables:
cp .env.example .env # Edit .env with your values
-
Start development server:
npm run dev
Available Scripts
npm run dev
- Start development servernpm run build
- Build for productionnpm run start
- Start production servernpm run lint
- Run ESLintnpm run lint:fix
- Fix ESLint issuesnpm run format
- Format code with Prettiernpm run test
- Run testsnpm run type-check
- Type check without emitting
Project Structure
src/
- Source codesrc/types/
- TypeScript type definitionssrc/utils/
- Utility functionssrc/services/
- Business logic servicessrc/config/
- Configuration files
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests and linting
- Submit a pull request
## Step 10: Performance Optimization
### Bundle Analysis
Install bundle analyzer:
```bash
npm install --save-dev webpack-bundle-analyzer
Add performance monitoring
npm install --save-dev speed-measure-webpack-plugin
Best Practices Summary
- Use strict TypeScript configuration - Catches more errors at compile time
- Set up proper linting and formatting - Ensures code consistency
- Configure path aliases - Makes imports cleaner and more maintainable
- Use environment variables - Keeps configuration separate from code
- Set up testing early - Makes it easier to maintain code quality
- Document everything - Helps with onboarding and maintenance
Common Issues and Solutions
Issue: Slow TypeScript compilation
Solution: Enable incremental compilation and use project references for large codebases.
Issue: Import paths getting messy
Solution: Use path aliases and organize code into logical modules.
Issue: Environment variables not typed
Solution: Create a typed config object and validate environment variables.
Issue: Inconsistent code formatting
Solution: Use Prettier with editor integration and pre-commit hooks.
This setup provides a solid foundation for any TypeScript project. You can customize it based on your specific needs, but this configuration will give you excellent developer experience from day one.
This guide is part of our Developer Experience Engineering series. Follow us for more TypeScript and DX optimization tips.
Related guides
Developer Experience Assessment Framework
A systematic approach to evaluating and improving your team's developer experience.
TypeScript Developer Experience Optimization
Learn how to optimize your TypeScript setup for better developer productivity and workflow efficiency.