Skip to main content

Root Directory Layout

Here’s the complete structure of an EverShop application:
my-evershop-app/
├── config/                    # Configuration files
│   ├── default.json          # Base configuration
│   ├── development.json      # Dev environment overrides
│   └── production.json       # Production environment overrides
├── extensions/                # Business logic modules
│   ├── offlinePayments/      # Payment extension
│   ├── productCatalog/       # Product management
│   ├── productReviews/       # Review system
│   └── sample/               # Example extension
├── themes/                    # Visual themes
│   └── anasuplements/        # Active theme
├── translations/              # Internationalization
│   └── es/                   # Spanish translations
├── public/                    # Static assets
│   └── favicon.ico
├── .evershop/                 # Build output (DO NOT EDIT)
├── node_modules/              # Dependencies (DO NOT EDIT)
├── package.json               # Project dependencies
└── .gitignore                 # Git exclusions
Important: Never modify files in .evershop/ or node_modules/. These directories are auto-generated.

Extension Structure

Extensions contain all business logic for your application. Here’s the detailed structure:

Example: Sample Extension

extensions/sample/
├── src/
│   ├── api/                   # REST API endpoints
│   │   └── createFoo/
│   │       ├── route.json     # Route configuration
│   │       ├── bodyParser.ts  # Middleware
│   │       └── [bodyParser]createFoo.ts  # Main handler
│   ├── pages/                 # Page components
│   │   └── frontStore/
│   │       └── homepage/
│   │           └── FooList.tsx
│   ├── graphql/              # GraphQL definitions
│   │   └── types/
│   │       └── Foo/
│   │           └── Foo.graphql
│   ├── subscribers/          # Event handlers
│   │   └── product_created/
│   │       └── productCreatedHandler.ts
│   ├── crons/                # Scheduled jobs
│   │   └── everyMinute.ts
│   └── bootstrap.ts          # Extension initialization
├── dist/                     # Compiled output (auto-generated)
├── package.json              # Extension dependencies
├── tsconfig.json             # TypeScript config
└── Readme.md
src/api/
directory
REST API endpoints with route configurationStructure: api/[endpointName]/
  • route.json - Defines HTTP methods, path, and access control
  • [middleware]handler.ts - Request handlers with middleware chain
src/pages/
directory
React page components for admin or frontStoreStructure: pages/[area]/[pageName]/ComponentName.tsx
  • Exports default component, layout, and optionally query
src/graphql/
directory
GraphQL type definitions and resolversStructure: graphql/types/[TypeName]/
  • TypeName.graphql - Schema definition
  • TypeName.resolvers.js - Query/mutation resolvers
src/subscribers/
directory
Event handlers that respond to system eventsStructure: subscribers/[event_name]/handler.ts
src/crons/
directory
Scheduled background jobsStructure: crons/jobName.ts
  • Registered in bootstrap.ts
bootstrap.ts
file
Extension initialization file that runs on startup
  • Register cron jobs
  • Set up database connections
  • Configure services

Real Example: API Endpoint

Here’s how the sample extension defines a REST API:
{
  "methods": ["POST"],
  "path": "/foos",
  "access": "private"
}
The [bodyParser] prefix means this middleware runs after the bodyParser middleware in the chain.

Theme Structure

Themes handle visual presentation only. They should NOT contain business logic.

Example: Anasuplements Theme

themes/anasuplements/
├── src/
│   └── pages/
│       ├── account/           # Account-related pages
│       │   ├── Dashboard.tsx
│       │   ├── Login.tsx
│       │   └── Register.tsx
│       ├── all/               # Components for all pages
│       │   ├── Header.tsx
│       │   └── Footer.tsx
│       └── homepage/          # Homepage-specific components
├── dist/                      # Compiled output (auto-generated)
├── package.json
└── tsconfig.json
pages/all/
directory
Components that appear on every pageExamples:
  • Header navigation
  • Footer
  • Cookie consent banners
pages/account/
directory
Components for account-related pagesExamples:
  • Login forms
  • Registration
  • Dashboard
pages/homepage/
directory
Components for the homepage onlyExamples:
  • Hero sections
  • Featured products
  • Promotional banners

Real Example: Header Component

themes/anasuplements/src/pages/all/Header.tsx
import React from 'react';

type HeaderProps = {
  storeName?: string;
  categories?: { name: string; url: string; }[];
};

export default function Header({ 
  storeName = "Ana's Suplements", 
  categories = [] 
}: HeaderProps) {
  return (
    <header className="bg-[#F8FAF9] border-b border-[#E8F5E9]">
      <div className="container mx-auto px-4 py-4">
        <div className="flex items-center justify-between">
          <a href="/" className="text-2xl font-bold text-[#2D5A3D]">
            {storeName}
          </a>
          
          <nav className="hidden md:flex space-x-6">
            {categories.map((category, index) => (
              <a 
                key={index} 
                href={category.url}
                className="text-[#4A5568] hover:text-[#2D5A3D] transition-colors"
              >
                {category.name}
              </a>
            ))}
          </nav>
        </div>
      </div>
    </header>
  );
}

export const layout = {
  areaId: 'header',
  sortOrder: 1
};
The theme uses custom colors (#2D5A3D for primary green) defined in the design system.

File Naming Conventions

API Endpoints

api/[endpointName]/[middlewareName]handler.ts
Rules:
  • Middleware prefix [name] determines execution order
  • Alphabetical sorting: [authenticate] runs before [bodyParser]
  • The final handler typically has the endpoint name

Page Components

pages/[area]/[pageName]/ComponentName.tsx
Rules:
  • Use PascalCase for component files
  • Area determines where component renders: all, frontStore, admin, account
  • Must export default function and layout object

GraphQL Types

graphql/types/[TypeName]/[TypeName].graphql
graphql/types/[TypeName]/[TypeName].resolvers.js

Subscribers

subscribers/[event_name]/handler.ts

Cron Jobs

crons/jobName.ts

TypeScript Configuration

Both extensions and themes use TypeScript:
extensions/sample/tsconfig.json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ES2022",
    "moduleResolution": "node",
    "esModuleInterop": true,
    "strict": true,
    "skipLibCheck": true,
    "outDir": "./dist",
    "rootDir": "./src"
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}
Extensions and themes are compiled separately during the build process.

Package Structure

Root Package

package.json
{
  "name": "my-evershop-app",
  "version": "0.1.0",
  "type": "module",
  "private": true,
  "scripts": {
    "setup": "evershop install",
    "start": "evershop start",
    "build": "evershop build",
    "dev": "evershop dev"
  },
  "dependencies": {
    "@evershop/evershop": "2.1.1"
  },
  "devDependencies": {
    "@types/express": "5.0.6",
    "@types/node": "25.3.3",
    "@types/react": "19.2.14",
    "typescript": "5.9.3"
  }
}

Extension Package

extensions/sample/package.json
{
  "name": "sample-evershop-extension",
  "version": "1.0.0",
  "main": "index.js",
  "type": "module",
  "scripts": {
    "tsc": "tsc"
  }
}

Theme Package

themes/anasuplements/package.json
{
  "name": "anasuplements",
  "version": "1.0.0",
  "private": true,
  "main": "src/index.ts",
  "scripts": {
    "build": "evershop build:theme"
  },
  "devDependencies": {
    "@types/react": "^19.0.0"
  }
}

Static Assets

Place public files in the public/ directory:
public/
├── favicon.ico
├── images/
│   ├── logo.png
│   └── banner.jpg
└── fonts/
    └── custom-font.woff2
Files in public/ are served at the root URL. For example, public/favicon.ico is accessible at /favicon.ico.

Translations

Store internationalization files in translations/:
translations/
├── es/              # Spanish
│   ├── common.json
│   └── products.json
└── en/              # English
    ├── common.json
    └── products.json

Build Output

During build, EverShop generates:
.evershop/               # Compiled application
├── build/              # Server-side code
└── public/             # Client-side bundles

extensions/*/dist/      # Compiled extensions
themes/*/dist/          # Compiled themes
These directories are in .gitignore and should never be committed to version control.

Working with Structure

1

Create Extension

mkdir -p extensions/myExtension/src
cd extensions/myExtension
npm init -y
2

Register in Config

Add to config/default.json:
{
  "system": {
    "extensions": [
      {
        "name": "myExtension",
        "resolve": "extensions/myExtension",
        "enabled": true
      }
    ]
  }
}
3

Add TypeScript Config

Copy tsconfig.json from extensions/sample/
4

Build and Run

npm run dev

Next Steps

Configuration System

Learn how config files control extensions and themes

Create Extension

Build your first custom extension