--- 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; ```