How to properly deprecate
Published: 2022-02-10 15:42:09

## Why would I deprecate?

Sometimes you release a function or widget with your library and you later think "wow I could have done that better." After all, if you're not looking back at your old code and thinking "who wrote this" then you're not improving as a developer.

But... you can't just delete that function in your next library release. If you did that, your consumers would get 💥 a in their build, or (if they're not using static compilation like TypeScript) the end user will get a bug in production. 🤕

So you've got to give your library's consumers some advanced notice. 

## How to do it

1. Make a plan to only remove the item from your next major version (i.e. **x**.1.1) This is because users only expect functionality removal in major versions due to how [SemVer](https://semver.org/) works.
2. In your next patch version (i.e. 1.1.**x**), plan to do the next steps
3. Add a `@deprecated` JSDoc tag to the JSDoc comment for that function/class/component. See an example of how to do that in the [JSDoc website](https://jsdoc.app/tags-deprecated.html).
4. Since the JSDoc tag only helps developers if they have [eslint-plugin-import/no-deprecated](https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-deprecated.md) and/or [eslint-plugin-deprecated-props](https://github.com/Drawbotics/eslint-plugin-deprecated-props) installed, you should do the developer a favor by using `console.warn` when that function or property is used. I'll provide an example below.
5. Here's the most important step: tell your consumers about the upcoming change. That means updating your release notes to explain that the item is going to be removed soon. It also means sharing it with your twitter followers, your Slack channel, dev.to, and (if your library is private) share it in your company's internal communications. Do you have to do this last step? Sure, you could skip it since the steps above will give runtime and compilation time feedback... however, why not give your users advanced heads up?

## Bringing it all together

Here's how you'd deprecate a function:
```typescript
/**
 * this is what you get when you trust a mouse talk show
 * @deprecated please use our new function mult instead
 * @returns {Number}
 */
export function multiply(a, b) {
  return a * b;
}
```

Here's how you'd deprecate a property in a function. This is only possible in TypeScript (see [source](https://stackoverflow.com/a/42457901/706768)).
```typescript
interface ComponentProps {
  /**
   * Some prop that is going to be removed in the future
   * @deprecated This will be removed soon in favor of colorHex
   */
  colorName?: string;
  colorHex: string;
  someOtherProp: string;
}

/**
 * Note that the @deprecated prop is used in the implementation
 * since it should still work. This does not throw a warning per se.
 */
const Component = ({ colorHex, colorName, someOtherProp }: ComponentProps) => {
  if(colorName){
    console.warn('colorName is deprecated. Please use colorHex instead');
  }
  const colorClassName = determineClassName(colorHex, colorName);
  return <div className={colorClassName}>{someOtherProp}</div>;
};
```

Side note, isn't it cool that VSCode shows that `colorName` is deprecated by putting a strikethrough style on it?

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1ds59bivlgka3ef0lmpz.png)

## Any questions?

Given how quickly the "developer experience" (DX) area is evolving, I'm sure there are improvements on this approach. So please comment below if you have suggestions, questions, or tips. Thanks for reading! :)