> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/Antony-Figueroa/my-evershop-app/llms.txt
> Use this file to discover all available pages before exploring further.

# Creating Extensions

> Learn how to create custom extensions in EverShop

Extensions are the primary way to add custom functionality to your EverShop store. They allow you to encapsulate features like API endpoints, event subscribers, cron jobs, and GraphQL types without modifying the core codebase.

## What is an Extension?

An extension is a modular package that can contain:

* **API Endpoints** - RESTful routes for custom operations
* **Event Subscribers** - React to system events
* **Cron Jobs** - Scheduled background tasks
* **GraphQL Types** - Custom data types and resolvers
* **Page Components** - Server-side rendered React components
* **Middleware** - Custom request processing logic

## Directory Structure

A typical extension follows this structure:

```
extensions/[extension-name]/
├── src/
│   ├── api/              # REST API endpoints
│   ├── subscribers/      # Event subscribers
│   ├── crons/           # Scheduled jobs
│   ├── graphql/         # GraphQL types & resolvers
│   ├── pages/           # Page components
│   └── bootstrap.ts     # Extension initialization
├── dist/                # Compiled output (auto-generated)
├── package.json
└── tsconfig.json
```

## Creating Your First Extension

<Steps>
  ### Create the Extension Directory

  Create a new directory in the `extensions` folder:

  ```bash theme={null}
  mkdir -p extensions/my-extension/src
  cd extensions/my-extension
  ```

  ### Initialize package.json

  Create a `package.json` file:

  ```json theme={null}
  {
    "name": "my-extension",
    "version": "1.0.0",
    "main": "index.js",
    "type": "module",
    "scripts": {
      "tsc": "tsc"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "description": ""
  }
  ```

  ### Configure TypeScript

  Create a `tsconfig.json` file:

  ```json theme={null}
  {
    "compilerOptions": {
      "module": "NodeNext",
      "target": "ES2018",
      "lib": ["dom", "dom.iterable", "esnext"],
      "esModuleInterop": true,
      "forceConsistentCasingInFileNames": true,
      "skipLibCheck": true,
      "declaration": true,
      "sourceMap": true,
      "allowJs": true,
      "checkJs": false,
      "jsx": "react",
      "outDir": "./dist",
      "resolveJsonModule": true,
      "allowSyntheticDefaultImports": true,
      "allowArbitraryExtensions": true,
      "strictNullChecks": true,
      "isolatedModules": false,
      "baseUrl": ".",
      "rootDir": "./src"
    },
    "include": ["src"]
  }
  ```

  ### Register the Extension

  Add your extension to `config/default.json`:

  ```json theme={null}
  {
    "system": {
      "extensions": [
        {
          "name": "my-extension",
          "resolve": "extensions/my-extension",
          "enabled": true
        }
      ]
    }
  }
  ```

  <Warning>
    Changes to `config/default.json` require running `npm run build` to take effect.
  </Warning>

  ### Build the Extension

  Run the build command to compile your extension:

  ```bash theme={null}
  npm run build
  ```
</Steps>

## Bootstrap File

The `bootstrap.ts` file is the entry point for your extension. It's executed when the application starts and is ideal for registering cron jobs, initializing services, or performing setup tasks.

### Example: Registering a Cron Job

Here's a real example from the sample extension:

```typescript title="src/bootstrap.ts" theme={null}
import path from 'path';
import { registerJob } from '@evershop/evershop/lib/cronjob';

export default function () {
  registerJob({
    name: 'sampleJob',
    schedule: '*/1 * * * *', // Runs every minute
    resolve: path.resolve(import.meta.dirname, 'crons', 'everyMinute.js'),
    enabled: true
  });
}
```

<Note>
  The `bootstrap.ts` file is optional. Only create it if you need to perform initialization tasks.
</Note>

## Extension Configuration

### Enabling/Disabling Extensions

To enable or disable an extension, modify `config/default.json`:

```json theme={null}
{
  "system": {
    "extensions": [
      {
        "name": "sample",
        "resolve": "extensions/sample",
        "enabled": true  // Set to false to disable
      }
    ]
  }
}
```

### Environment-Specific Configuration

You can override settings in environment-specific config files:

<CodeGroup>
  ```json title="config/development.json" theme={null}
  {
    "system": {
      "extensions": [
        {
          "name": "sample",
          "enabled": true
        }
      ]
    }
  }
  ```

  ```json title="config/production.json" theme={null}
  {
    "system": {
      "extensions": [
        {
          "name": "sample",
          "enabled": false
        }
      ]
    }
  }
  ```
</CodeGroup>

## Real-World Example: Sample Extension

The EverShop repository includes a complete sample extension that demonstrates all extension features:

```
extensions/sample/
├── src/
│   ├── api/
│   │   └── createFoo/
│   │       ├── route.json
│   │       ├── bodyParser.ts
│   │       └── [bodyParser]createFoo.ts
│   ├── subscribers/
│   │   └── product_created/
│   │       └── consoleLog.js
│   ├── crons/
│   │   └── everyMinute.ts
│   ├── graphql/
│   │   └── types/
│   │       └── Foo/
│   │           ├── Foo.graphql
│   │           └── Foo.resolvers.js
│   ├── pages/
│   │   └── frontStore/
│   │       └── homepage/
│   │           └── FooList.tsx
│   └── bootstrap.ts
├── package.json
└── tsconfig.json
```

## Best Practices

<Tip>
  **Use TypeScript**: Always use TypeScript (`.ts`/`.tsx`) for new code to benefit from type safety and better developer experience.
</Tip>

* **Modular Organization** - Keep related files together in feature-specific directories
* **Naming Conventions** - Use descriptive names that reflect the extension's purpose
* **Environment Variables** - Store sensitive data in `.env` files, not in configuration
* **Error Handling** - Always implement proper error handling in API endpoints and subscribers
* **Documentation** - Include a `Readme.md` file explaining what your extension does

## Common Patterns

### Extension with API Only

```
extensions/payment-gateway/
├── src/
│   └── api/
│       ├── webhook/
│       └── process-payment/
└── package.json
```

### Extension with Subscribers Only

```
extensions/email-notifications/
├── src/
│   └── subscribers/
│       ├── order_placed/
│       ├── order_shipped/
│       └── customer_registered/
└── package.json
```

### Extension with GraphQL

```
extensions/custom-data/
├── src/
│   └── graphql/
│       └── types/
│           ├── CustomType/
│           └── AnotherType/
└── package.json
```

## Troubleshooting

### Extension Not Loading

1. Verify the extension is registered in `config/default.json`
2. Ensure `enabled` is set to `true`
3. Run `npm run build` to rebuild the application
4. Check for TypeScript compilation errors

### Build Errors

1. Verify `tsconfig.json` is properly configured
2. Check that all imports are correct
3. Ensure dependencies are installed: `npm install`

## Next Steps

<CardGroup cols={2}>
  <Card title="API Endpoints" icon="globe" href="/guides/api-endpoints">
    Learn how to create RESTful API endpoints
  </Card>

  <Card title="Event Subscribers" icon="bell" href="/guides/event-subscribers">
    React to system events with subscribers
  </Card>

  <Card title="Cron Jobs" icon="clock" href="/guides/cron-jobs">
    Schedule background tasks
  </Card>

  <Card title="Page Components" icon="window" href="/guides/page-components">
    Build custom page components
  </Card>
</CardGroup>
