Many dev teams get split over formatting. And their typical day looks like this: you come to work, have some coffee, write some code, everything’s fine — then bam! Code review where you’re told you put a brace in the wrong place.

image

It was an everyday reality for one of Skyeng dev teams a year ago. Then someone had enough and said, “Guys, from now on we use Prettier. Is everyone ok with that?” And then there were no more debates about formatting. We’ve installed Prettier in the frontend repo and all the teams use it.

What is Prettier?
image
Prettier is a code formatter with support for many instruments including our beloved Angular and Typescript. Prettier doesn’t modify code replacing ternary operators with if’s or splitting a long string into several concatenated ones — it’s the developer’s job. Prettier just enforces a consistent code style across the entire codebase.

The way it was


At that point, Skyeng already had several dozens of developers and was hiring 10–20 new people every month. They worked (and still do) in smaller teams, each being a separate unit with its own deadlines and commitments.

Let’s imagine such a team (all the characters are fictitious):

Boris is a middle developer. He used to work at a big corporation with its own style guide but does his best to adopt our style. He’s doing just fine but every now and gets comments about wrong formatting at a code review. Pretty annoying.

Pavel is a more experienced developer. He’s good at his job, never misses a deadline but doesn’t care much about code style. He has his own style. As a result, his code is good and solid but doesn’t fit well into a big project.

Alex is a perfectionist. “Clean code is good code” is his philosophy. He doesn’t accept poorly formatted code and sends it back with comments like “put this curly brace on a new line.” And Boris would waste time fixing formatting while Pavel would spend hours arguing “If you don’t like it, fix it yourself.”

The way it is now


Prettier helps you forget about formatting while requiring minimal setting. That was the real clincher for Pavel when Alex texted to the team chat:

  • Installed Prettier


  • Made a couple of comments on the Prettier code style (like, it puts if logic operations at the end of a string, not at the beginning)

And that’s all, now everyone in the team works with Prettier. We’ve been using it since late January 2019 and have saved tons of time on arguments about formatting.

Here are some examples of Skyeng production code before and after Prettier


We modified the code a little bit to showcase Prettier’s features.

Before:

  public listenDndForFocusEvents(channel: string): Observable<boolean> {
    return this.drag
      .pipe(
        filter(
          event => event.channel === channel
        ), 
        filter(
          event => event instanceof DndDragStartEvent || event instanceof DndDragEndEvent
        ), 
        map(
          event => event instanceof DndDragStartEvent
        )
      )
  }

After:

  public listenDndForFocusEvents(channel: string): Observable<boolean> {
    return this.drag.pipe(
      filter(event => event.channel === channel),
      filter(event => event instanceof DndDragStartEvent || event instanceof DndDragEndEvent),
      map(event => event instanceof DndDragStartEvent),
    );
  }

Even it had been one string, Prettier would have formatted it the right way:

public listenDndForFocusEvents(channel: string): Observable<boolean> {
    return this.drag.pipe(filter(event => event.channel === channel), filter(event => event instanceof DndDragStartEvent || event instanceof DndDragEndEvent), map(event => event instanceof DndDragStartEvent),);
  }

Another piece of code, without a semicolon:

const lessonCount$ = this.studentLessonsCounterService
      .getCounter().pipe(map(featureInfo => featureInfo.lessonCount))
    const isItTimeForNotification$ = lessonCount$.pipe(map(lessonCount => lessonCount % REAL_TALK_NOTIFICATION_LESSON_INTERVAL === 0))

After:

const lessonCount$ = this.studentLessonsCounterService
      .getCounter()
      .pipe(map(featureInfo => featureInfo.lessonCount));
const isItTimeForNotification$ = lessonCount$.pipe(
      map(lessonCount => lessonCount % REAL_TALK_NOTIFICATION_LESSON_INTERVAL === 0),
    );

Now our code reviews take less time, Boris doesn’t spend hours on formatting, Pavel writes with his own style and it doesn’t bother anyone and Alex is finally happy that the code is nice and clean. We forgot about formatting and focused on more important things.