+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Part 253 of 355

📘 Prettier Integration: Code Formatting

Master prettier integration: code formatting in TypeScript with practical examples, best practices, and real-world applications 🚀

🚀Intermediate
30 min read

Prerequisites

  • Basic understanding of JavaScript 📝
  • TypeScript installation ⚡
  • VS Code or preferred IDE 💻

What you'll learn

  • Understand Prettier fundamentals 🎯
  • Apply Prettier in real projects 🏗️
  • Debug common formatting issues 🐛
  • Write consistent, beautiful code ✨

🎯 Introduction

Welcome to this exciting tutorial on Prettier Integration! 🎉 In this guide, we’ll explore how to automatically format your TypeScript code for maximum readability and consistency.

You’ll discover how Prettier can transform your TypeScript development experience. Whether you’re building web applications 🌐, server-side code 🖥️, or libraries 📚, understanding Prettier is essential for writing clean, maintainable code that looks professional.

By the end of this tutorial, you’ll feel confident setting up and using Prettier in your own projects! Let’s dive in! 🏊‍♂️

📚 Understanding Prettier

🤔 What is Prettier?

Prettier is like having a professional stylist 🎨 for your code! Think of it as an automatic formatting assistant that takes your messy, inconsistent code and makes it beautiful and consistent every time.

In TypeScript terms, Prettier is an opinionated code formatter that automatically formats your code according to consistent rules ✨. This means you can:

  • ✨ Stop worrying about spacing and indentation
  • 🚀 Focus on logic instead of formatting
  • 🛡️ Ensure consistent code across your entire team
  • 💪 Eliminate formatting debates forever

💡 Why Use Prettier?

Here’s why developers love Prettier:

  1. Consistency 🎯: Everyone’s code looks the same
  2. Time Savings ⚡: No more manual formatting
  3. Fewer Merge Conflicts 🤝: Consistent formatting reduces Git conflicts
  4. Better Readability 📖: Clean code is easier to understand

Real-world example: Imagine working on a team project 👥. Without Prettier, each developer might format their code differently, making code reviews a nightmare. With Prettier, everyone’s code looks identical! 🌟

🔧 Basic Syntax and Usage

📝 Installation

Let’s start by installing Prettier:

# 📦 Install Prettier globally
npm install -g prettier

# 🏗️ Or install locally in your project
npm install --save-dev prettier

# 🎨 For TypeScript projects, also install:
npm install --save-dev @typescript-eslint/parser

💡 Explanation: We install Prettier as a dev dependency since it’s only needed during development, not in production!

🎯 Basic Configuration

Create a .prettierrc file in your project root:

{
  "semi": true,
  "trailingComma": "es5",
  "singleQuote": true,
  "printWidth": 80,
  "tabWidth": 2,
  "useTabs": false
}

🎨 Let’s break this down:

  • semi: Add semicolons at the end of statements ✨
  • trailingComma: Add trailing commas where valid 🎯
  • singleQuote: Use single quotes instead of double quotes 📝
  • printWidth: Maximum line length before wrapping 📏
  • tabWidth: Number of spaces per indentation level 🎚️
  • useTabs: Use spaces instead of tabs 🔄

💡 Practical Examples

🛒 Example 1: E-Commerce Store

Let’s format a messy TypeScript class:

// ❌ Before Prettier - messy and inconsistent
interface Product{id:string;name:string;price:number;inStock:boolean;
categories:string[];}

class ShoppingCart{
private items:Product[]=[];

addItem(product:Product):void{
this.items.push(product);console.log(`Added ${product.name} to cart!`);}

getTotal():number{return this.items.reduce((sum,item)=>sum+item.price,0);}
}

// ✅ After Prettier - clean and consistent!
interface Product {
  id: string;
  name: string;
  price: number;
  inStock: boolean;
  categories: string[];
}

class ShoppingCart {
  private items: Product[] = [];

  addItem(product: Product): void {
    this.items.push(product);
    console.log(`Added ${product.name} to cart! 🛍️`);
  }

  getTotal(): number {
    return this.items.reduce((sum, item) => sum + item.price, 0);
  }
}

🎯 Try it yourself: Copy the messy code into a .ts file and run prettier --write filename.ts!

🎮 Example 2: Game Configuration

Let’s see Prettier handle complex objects:

// ❌ Before - hard to read configuration
const gameSettings={player:{name:"Hero",level:1,health:100,mana:50,inventory:["sword","potion","map"]},
world:{difficulty:"normal",enemies:[{type:"goblin",health:30},{type:"orc",health:80}],
treasures:[{name:"gold",value:100},{name:"gem",value:500}]}}

// ✅ After Prettier - beautifully formatted!
const gameSettings = {
  player: {
    name: 'Hero',
    level: 1,
    health: 100,
    mana: 50,
    inventory: ['sword', 'potion', 'map'],
  },
  world: {
    difficulty: 'normal',
    enemies: [
      { type: 'goblin', health: 30 },
      { type: 'orc', health: 80 },
    ],
    treasures: [
      { name: 'gold', value: 100 },
      { name: 'gem', value: 500 },
    ],
  },
};

// 🎯 Type-safe game manager
class GameManager {
  private settings: typeof gameSettings;

  constructor(settings: typeof gameSettings) {
    this.settings = settings;
  }

  // 🎮 Start new game
  startGame(): void {
    console.log(`🎮 Starting game with ${this.settings.player.name}!`);
    console.log(`💪 Health: ${this.settings.player.health}`);
    console.log(`⚡ Mana: ${this.settings.player.mana}`);
  }

  // 👾 Get random enemy
  getRandomEnemy() {
    const enemies = this.settings.world.enemies;
    const randomIndex = Math.floor(Math.random() * enemies.length);
    return enemies[randomIndex];
  }
}

🏗️ Example 3: VS Code Integration

Set up automatic formatting in VS Code:

// 📁 .vscode/settings.json
{
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "[typescript]": {
    "editor.formatOnSave": true,
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[typescriptreact]": {
    "editor.formatOnSave": true,
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  }
}

🚀 Advanced Concepts

🧙‍♂️ Custom Prettier Configuration

For advanced projects, create more sophisticated rules:

// 📁 prettier.config.js
module.exports = {
  // 🎯 Basic formatting
  semi: true,
  trailingComma: 'all',
  singleQuote: true,
  printWidth: 100,
  tabWidth: 2,
  useTabs: false,
  
  // 🎨 Advanced options
  bracketSpacing: true,
  bracketSameLine: false,
  arrowParens: 'avoid',
  endOfLine: 'lf',
  
  // 📝 Override for specific files
  overrides: [
    {
      files: '*.json',
      options: {
        printWidth: 200,
      },
    },
    {
      files: '*.md',
      options: {
        proseWrap: 'always',
      },
    },
  ],
};

🏗️ Integration with ESLint

Create a seamless workflow with ESLint:

# 🛠️ Install ESLint + Prettier integration
npm install --save-dev eslint eslint-config-prettier eslint-plugin-prettier
// 📁 .eslintrc.json
{
  "extends": [
    "@typescript-eslint/recommended",
    "prettier"
  ],
  "plugins": ["prettier"],
  "rules": {
    "prettier/prettier": "error"
  }
}

🚀 Git Hooks with Husky

Automatically format code before commits:

# 📦 Install Husky and lint-staged
npm install --save-dev husky lint-staged
// 📁 package.json
{
  "scripts": {
    "prepare": "husky install"
  },
  "lint-staged": {
    "*.{ts,tsx,js,jsx}": [
      "prettier --write",
      "eslint --fix",
      "git add"
    ]
  }
}

⚠️ Common Pitfalls and Solutions

😱 Pitfall 1: Conflicting with ESLint

// ❌ ESLint and Prettier fighting each other
// ESLint wants double quotes, Prettier wants single quotes
const message: string = "This causes conflicts! 😰";

// ✅ Solution: Configure them to work together
// Use eslint-config-prettier to disable conflicting rules
const message: string = 'Now they work together! 🤝';

🤯 Pitfall 2: Formatting Breaking Code

// ❌ Prettier might break template literals
const longQuery = `
  SELECT *
  FROM users
  WHERE name LIKE '%john%'
  AND age > 18
`;

// ✅ Use prettier-ignore for special cases
// prettier-ignore
const longQuery = `
  SELECT *
  FROM users
  WHERE name LIKE '%john%'
    AND age > 18
`;

🚫 Pitfall 3: Overriding User Preferences

// ❌ Forcing team members to use your personal style
{
  "printWidth": 200,  // Too wide for most screens!
  "tabWidth": 8       // Way too much indentation!
}

// ✅ Use sensible defaults that work for everyone
{
  "printWidth": 80,   // Readable on all screens 📱💻
  "tabWidth": 2       // Clean, not overwhelming 🎯
}

🛠️ Best Practices

  1. 🎯 Use Project-Wide Configuration: Create .prettierrc in your project root
  2. 📝 Integrate with Your Editor: Set up auto-format on save
  3. 🤝 Team Consistency: Share configuration files in version control
  4. ✨ Combine with Linting: Use ESLint + Prettier for best results
  5. 🔄 Automate with Git Hooks: Format code automatically before commits
  6. 📖 Document Your Rules: Explain why you chose specific configurations
  7. 🎨 Keep It Simple: Don’t over-configure - Prettier’s defaults are good!

🧪 Hands-On Exercise

🎯 Challenge: Format a Messy TypeScript Project

Create a complete formatting setup for a TypeScript project:

📋 Requirements:

  • ✅ Install and configure Prettier
  • 🛠️ Set up ESLint integration
  • 📁 Create VS Code workspace settings
  • 🎯 Add pre-commit hooks
  • 🎨 Format a complex TypeScript file
  • 📝 Create a style guide document

🚀 Bonus Points:

  • Add custom overrides for different file types
  • Set up different configs for development vs production
  • Create npm scripts for formatting

💡 Solution

🔍 Click to see solution
# 🎯 Step 1: Initialize project and install dependencies
npm init -y
npm install --save-dev prettier eslint @typescript-eslint/parser eslint-config-prettier eslint-plugin-prettier husky lint-staged
// 📁 .prettierrc
{
  "semi": true,
  "trailingComma": "es5",
  "singleQuote": true,
  "printWidth": 80,
  "tabWidth": 2,
  "useTabs": false,
  "bracketSpacing": true,
  "arrowParens": "avoid"
}
// 📁 .eslintrc.json
{
  "parser": "@typescript-eslint/parser",
  "extends": [
    "@typescript-eslint/recommended",
    "prettier"
  ],
  "plugins": ["prettier"],
  "rules": {
    "prettier/prettier": "error"
  }
}
// 📁 .vscode/settings.json
{
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  },
  "[typescript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  }
}
// 📁 package.json (add these scripts)
{
  "scripts": {
    "format": "prettier --write \"src/**/*.{ts,tsx,js,jsx,json,css,md}\"",
    "format:check": "prettier --check \"src/**/*.{ts,tsx,js,jsx,json,css,md}\"",
    "lint": "eslint src --ext .ts,.tsx",
    "lint:fix": "eslint src --ext .ts,.tsx --fix",
    "prepare": "husky install"
  },
  "lint-staged": {
    "*.{ts,tsx,js,jsx}": [
      "prettier --write",
      "eslint --fix"
    ],
    "*.{json,css,md}": [
      "prettier --write"
    ]
  }
}
// 📁 src/example.ts - Before formatting (messy!)
interface User{id:number;name:string;email:string;preferences:{theme:'light'|'dark';notifications:boolean;};}

class UserManager{
private users:User[]=[];

addUser(user:User):void{
if(!user.email.includes('@')){throw new Error('Invalid email');}
this.users.push(user);console.log(`User ${user.name} added! 🎉`);}

getUserPreferences(userId:number):{theme:'light'|'dark';notifications:boolean;}|null{
const user=this.users.find(u=>u.id===userId);
return user?user.preferences:null;}
}

// 📁 After running prettier (clean!)
interface User {
  id: number;
  name: string;
  email: string;
  preferences: {
    theme: 'light' | 'dark';
    notifications: boolean;
  };
}

class UserManager {
  private users: User[] = [];

  addUser(user: User): void {
    if (!user.email.includes('@')) {
      throw new Error('Invalid email');
    }
    this.users.push(user);
    console.log(`User ${user.name} added! 🎉`);
  }

  getUserPreferences(
    userId: number
  ): { theme: 'light' | 'dark'; notifications: boolean } | null {
    const user = this.users.find(u => u.id === userId);
    return user ? user.preferences : null;
  }
}
# 🎯 Step 2: Set up git hooks
npx husky install
npx husky add .husky/pre-commit "npx lint-staged"

# 🎨 Step 3: Format your project
npm run format

# ✅ Step 4: Check formatting
npm run format:check

🎓 Key Takeaways

You’ve learned so much! Here’s what you can now do:

  • Set up Prettier with confidence in any TypeScript project 💪
  • Configure formatting rules that work for your team 🛡️
  • Integrate with ESLint for the perfect development workflow 🎯
  • Automate formatting with git hooks and editor integration 🐛
  • Create consistent, beautiful code that everyone can read! 🚀

Remember: Prettier is your friend that makes your code beautiful! Let it handle the formatting so you can focus on building amazing things. 🤝

🤝 Next Steps

Congratulations! 🎉 You’ve mastered Prettier integration!

Here’s what to do next:

  1. 💻 Set up Prettier in your current TypeScript project
  2. 🏗️ Configure your team’s shared formatting rules
  3. 📚 Explore our next tutorial: “ESLint Rules and Best Practices”
  4. 🌟 Share your beautifully formatted code with the world!

Remember: Consistent code formatting isn’t just about looks—it makes code reviews faster, reduces merge conflicts, and helps everyone write better code. Keep formatting, keep learning, and most importantly, enjoy writing beautiful TypeScript! 🚀


Happy coding! 🎉🚀✨