---
title: Plugins
path: /v5/plugins/
index: 14
---
Plugins are an extensible way to add functionality to tippy instances. By
splitting functionality into a plugin, components or routes that don't need the
plugin are not burdened with its bundle size cost.
### Exported plugins
These plugins are exported by the package:
- `animateFill`
- `followCursor`
- `inlinePositioning`
- `sticky`
Requires importing the following CSS stylesheets to work:
```js
import 'tippy.js/dist/backdrop.css';
import 'tippy.js/animations/shift-away.css';
```
### Usage
#### CDN (iife)
Included plugins (part of the [All Props](/all-props/) table) will work as
normal.
```js
tippy(targets, {
followCursor: true,
});
```
#### Node (esm or cjs)
```js
import tippy, {followCursor} from 'tippy.js';
tippy(targets, {
followCursor: true,
plugins: [followCursor],
});
```
### Creating your own custom plugin
A plugin is created by defining an object with the following shape:
```js
const plugin = {
// Optional (if the plugin provides a prop to use)
name: 'propName', // e.g. 'followCursor' or 'sticky'
defaultValue: 'anyValue',
// Required
fn(instance) {
// Internal state
return {
// Lifecycle hooks
};
},
};
```
The plugin's function `fn` returns an object of
[lifecycle hooks](/lifecycle-hooks/).
Here's an example of a plugin that causes a popper to hide if no elements within
it are in focus (for interactivity):
```js
const hideOnPopperBlur = {
name: 'hideOnPopperBlur',
defaultValue: true,
fn(instance) {
return {
onCreate() {
instance.popper.addEventListener('focusout', (event) => {
if (
instance.props.hideOnPopperBlur &&
event.relatedTarget &&
!instance.popper.contains(event.relatedTarget)
) {
instance.hide();
}
});
},
};
},
};
// Our new prop is enabled by default (defaultValue: true)
tippy(targets, {
plugins: [hideOnPopperBlur],
});
```
Plugins are invoked per-instance and the plugin function definition takes the
instance as an argument, so you can use private variables to create internal
state in the plugin closure. This is how the `followCursor` plugin works.
### TypeScript
Types that take `Props` (e.g. `Tippy`, `Delegate`, `CreateSingleton`) are
generics that accept an extended props interface:
```ts
import tippy, {Tippy, Props, Plugin, LifecycleHooks} from 'tippy.js';
interface CustomProps {
myCustomProp: boolean;
}
type FilteredProps = CustomProps &
Omit;
type ExtendedProps = FilteredProps & LifecycleHooks;
export const myCustomProp: Plugin = {
name: 'myCustomProp',
defaultValue: false,
fn: () => ({}),
};
export default (tippy as unknown) as Tippy;
```