--- title: Plugins label: Overview order: 10 desc: Plugins provide a great way to modularize Payload functionalities into easy-to-use enhancements and extensions of your Payload apps. keywords: plugins, config, configuration, extensions, custom, documentation, Content Management System, cms, headless, javascript, node, react, express --- Payload comes with a built-in Plugins infrastructure that allows developers to build their own modular and easily reusable sets of functionality. Because we rely on a simple config-based structure, Payload plugins simply take in a user's existing config and return a modified config with new fields, hooks, collections, admin views, or anything else you can think of. Writing plugins is no more complex than writing regular JavaScript. If you know how [spread syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax) works and are up to speed with Payload concepts, writing a plugin will be a breeze. **Example use cases:** - Automatically sync data from a specific collection to HubSpot or a similar CRM when data is added or changes - Add password-protection functionality to certain documents - Add a full ecommerce backend to any Payload app - Add custom reporting views to Payload's admin panel - Encrypt specific collections' data - Add a full form builder implementation - Integrate all `upload`-enabled collections with a third-party file host like S3 or Cloudinary - Add custom routes or GraphQL queries / mutations with any type of custom functionality that you can think of ### How to install plugins The base Payload config allows for a `plugins` property which takes an `array` of [`Plugin`s](https://github.com/payloadcms/payload/blob/master/src/config/types.ts#L21). ```js import { buildConfig } from 'payload/config'; // note: these plugins are not real (yet?) import addLastModified from 'payload-add-last-modified'; import passwordProtect from 'payload-password-protect'; const config = buildConfig({ serverURL: 'http://localhost:3000', collections: [ { slug: 'pages', fields: [ { name: 'title', type: 'text', required: true, }, { name: 'content', type: 'richText', required: true, } ] } ], plugins: [ // Many plugins require options to be passed. // In the following example, we call the function // and pass it options accordingly passwordProtect(['pages']), // This plugin takes no options and just // needs to be passed directly addLastModified, // .. // To understand how to use the plugins you're interested in, // consult their corresponding documentation ] }); export default config; ``` #### When Plugins are initialized Payload Plugins are executed _after_ the incoming config is validated, sanitized, and default options are merged in. ## Simple example Here is an example for how to automatically add a `lastModifiedBy` field to all Payload collections using a Plugin written in TypeScript. ```js import { Config } from 'payload/config'; import { CollectionConfig } from 'payload/dist/collections/config/types'; const addLastModified = (incomingConfig: Config): Config => { // Find all incoming auth-enabled collections // so we can create a lastModifiedBy relationship field // to all auth collections const authEnabledCollections = incomingConfig.collections.find( collection => Boolean(collection.auth) ); // Spread the existing config const config: Config = { ...incomingConfig, collections: incomingConfig.collections.map((collection) => { // Spread each item that we are modifying, // and add our new field - complete with // hooks and proper admin UI config return { ...collection, fields: [ ...collection.fields, { name: 'lastModifiedBy', type: 'relationship', relationTo: authEnabledCollections.map(({ slug }) => slug), hooks: { beforeChange: [ ({ req }) => ({ value: req?.user?.id, relationTo: req?.user?.collection, }), ] }, admin: { position: 'sidebar', readOnly: true, }, }, ], }, }); }; return config; }; export default addLastModified; ``` #### More examples coming soon This page will be updated with more examples in the future, and we will be maintaining a list of both official and community Payload plugins on our website very soon. In the meantime, if you have built a plugin, or if you would like one to be built by the core Payload team, [open a Feature Request](https://github.com/payloadcms/payload/discussions) in our GitHub Discussions board. We would be happy to review your code and maybe feature you and your plugin on our website.