# Including Extensions

> Learn how to include extensions in your self-hosted Directus project.

All Directus projects can include extensions via the [Directus Marketplace](/guides/extensions/marketplace). Self-hosted projects can also install extensions directly from npm or by dropping extensions directly into the extensions directory mounted in your project.

## Directus Marketplace

By default, App extensions and API using our [Sandbox SDK](/guides/extensions/api-extensions/sandbox) are available from the Marketplace in all Directus projects. If you want to install API extensions that are not sandboxed, you can change the value of the [`MARKETPLACE_TRUST`](/configuration/extensions) variable.

## npm Packages

To install extensions, you will need to build a custom image of Directus.

<callout color="primary" icon="i-lucide-book-open" to="/self-hosting/hardened-images">

For the distroless `-dhi` image or running the Directus CLI on a hardened image, see [Hardened Images](/self-hosting/hardened-images).

</callout>

### 1. Modify Docker Compose File

If you are using a `docker-compose.yml` file, delete the `image` property and add a `build` section:

```yaml
build: 
  context: ./
```

### 2. Create a Dockerfile

At the root of your project, create a file called `Dockerfile`, if one doesn't already exist. The Directus image doesn't include `npm`, `npx`, or Corepack, so install the extension in a separate build stage and copy the result into the final image:

```dockerfile
# Build stage - a Node.js Alpine image with npm and Corepack
FROM node:22-alpine AS build

RUN corepack enable

WORKDIR /extension-build
RUN pnpm init
RUN pnpm add @directus-labs/spreadsheet-layout

# Final stage
FROM directus/directus:latest

COPY --from=build /extension-build/node_modules/@directus-labs/spreadsheet-layout /directus/extensions/spreadsheet-layout
```

This example installs the Spreadsheet Layout. Change the `pnpm add` line to install any extension published on npm, and add a `COPY` line for each one.

### 3. Build Docker Image

Build your Docker image by running `docker compose build` and then run `docker compose up` as normal to start the container.

## Directly Including Extensions

To locally install extensions, copy the files generated by building an extension into the `extensions` directory. By default, this is located at the root of your Directus project, but this can be changed using the [`EXTENSIONS_PATH`](/configuration/extensions) environment variable.

### 1. Mount Extensions Directory

At the root of your project, next to your `docker-compose.yml` file, create a new directory called `extensions`. Then, in your `docker-compose.yml` file, add the directory as a volume to the `directus` service section:

```yaml
services:
  directus:
    volumes:
      - ./extensions:/directus/extensions
```

### 2. Add Extensions

Inside of the `extensions` directory, create a new directory for each extension you want to install. Then, copy the files generated by building an extension into the directory.

```text
extensions/
  <extension-name>/
    dist/
      index.js
    package.json
  ...
```

At the very least you should have a `package.json` file and a `dist` directory with one or more files inside of it.

When you restart your Docker container, Directus will automatically load any extensions you have included in the directory.
