--- title: Customize and Build Your Own Plugins short: Custom Plugins type: plugins category: Overview cat: overview order: 8 meta_title: Plugins Frequently Asked Questions tier: enterprise --- You can modify the plugin examples that we provide or build your own custom plugins. Plugins are authored in JavaScript and are project-specific. They are limited to specific tasks and the annotation workflow and cannot, for example, be used to create new pages or otherwise extend the core functionality of Label Studio. !!! note Plugins are not available unless enabled. There are [important security considerations](/guide/plugins#Security-notes-constraints-and-limitations) to understand before requesting access. ## Execution Plugins are executed each time the annotation is displayed. For example, when you open a task, move between tasks, create a new annotation, switch between annotations, create a new annotation, and view older versions of the annotation. This means that for each annotation you can add specific behavior. However, it also means that if you don’t plan accordingly when constructing your plugin logic, you could end up with repetitive actions. To avoid multiple event subscriptions (and, consequently, multiple handler triggers), it is best to use `LSI.on()` because the handlers that are added using this method will be unsubscribed after the current annotation is closed. For more information on LSI, [see below](#Label-Studio-Interface-LSI). !!! note Because plugins can be executed multiple times for the same annotation, you need to take measures to avoid issues such as infinite loops, memory leaks, and application crashes. For this reason, we recommend that each script run cleans up the previous run, meaning that event handlers should be stored in a global register along with their parameters so that they can be checked, stopped, or adjusted. Every handler should check whether it is still running over the current version of annotation/data in case it has changed. However, handlers attached via `LSI.on()` are safe and will automatically handle this clean up process. !!! info Tip Plugins are executed within an asynchronous function, so you can use `await` as necessary. ## Troubleshooting and debugging It is important to test and refine plugins using a test project first to avoid any disruptions on live projects. When you add a plugin, the **Testing** panel appears below the script field. You can use this to test the plugin with sample data, manually trigger events, and see what events are triggered as you interact with the sample data.