---
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.

<Banner type="success">
	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.
</Banner>

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.
