> ## Documentation Index
> Fetch the complete documentation index at: https://sonamu.cartanova.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Project Structure

> Directory structure and key files of a Sonamu project

export const FileItem = ({name, description, children}) => {
  const isLeaf = !children;
  const ext = getFileExtension(name);
  const extStyle = ext ? getExtensionStyle(ext) : null;
  return <div style={{
    marginLeft: "30px"
  }}>
      <div style={{
    display: "flex",
    alignItems: "center",
    gap: "4px"
  }}>
        <span style={{
    position: "relative",
    display: "inline-block"
  }}>
          <span className="file-icon">{isLeaf && !name.endsWith("/") ? "📄" : "📁"}</span>
          {ext && <span style={{
    position: "absolute",
    bottom: "2px",
    right: "0px",
    fontSize: "5px",
    fontWeight: "bold",
    padding: "1px",
    borderRadius: "2px",
    lineHeight: "1",
    minWidth: "8px",
    textAlign: "center",
    ...extStyle
  }}>
              {ext}
            </span>}
        </span>
        <code>{name}</code>
        {description && <span className="description"> - {description}</span>}
      </div>
      {children}
    </div>;
};

export const FileTree = ({children}) => {
  return <div className="file-tree" style={{
    margin: "20px",
    marginLeft: "-30px"
  }}>
      {children}
    </div>;
};

A Sonamu project is structured as a monorepo that manages both the backend (api) and frontend (web) together.

## Overall Structure

<FileTree>
  <FileItem name="myapp/" description="Sonamu monorepo root">
    <FileItem name="node_modules/" />

    <FileItem name="packages/">
      <FileItem name="api/" description="Backend API server" />

      <FileItem name="web/" description="Frontend web application" />
    </FileItem>

    <FileItem name=".gitignore" />

    <FileItem name="pnpm-lock.yaml" />

    <FileItem name="pnpm-workspace.yaml" description="Workspace and dependency catalog" />

    <FileItem name="README.md" description="Project documentation" />
  </FileItem>
</FileTree>

<Frame caption="Complete directory structure of a Sonamu project opened in VS Code">
  <img src="https://mintcdn.com/cartanova-7788888c/mRzLpig-R41-Dqkz/images/projectStructure1.png?fit=max&auto=format&n=mRzLpig-R41-Dqkz&q=85&s=d5c8728e78404d4685e3b6b889acb7c5" alt="Complete project structure" style={{ maxWidth: "500px", width: "100%", borderRadius: "0.75rem" }} width="698" height="494" data-path="images/projectStructure1.png" />
</Frame>

### pnpm Workspace

The root `pnpm-workspace.yaml` manages packages and common dependency versions:

```yaml title="pnpm-workspace.yaml" theme={null}
packages:
  - packages/api
  - packages/web

catalog:
  "@tanstack/react-query": ^5.90.12
  "@tanstack/react-router": 1.143.11
  react: ^19.2.3
  vite: 7.3.0
  vitest: 4.0.16
  zod: ^4.1.12
  # ... other common dependencies
```

## API Directory (Backend)

### Root Files

<FileTree>
  <FileItem name="packages/api/">
    <FileItem name="src/" description="Source code" />

    <FileItem name="database/" description="Database related files" />

    <FileItem name="package.json" description="Dependencies and scripts" />

    <FileItem name="vitest.config.ts" description="Test configuration" />

    <FileItem name="tsconfig.json" description="TypeScript configuration" />

    <FileItem name="tsconfig.schemas.json" description="Schema generation config" />

    <FileItem name="tsconfig.types.json" description="Type generation config" />

    <FileItem name="custom-sequencer.ts" description="Test sequencer" />

    <FileItem name="tsdown.config.ts" description="Optional API build override for tsdown" />

    <FileItem name=".env" description="Environment variables (auto-generated)" />
  </FileItem>
</FileTree>

<Frame caption="Actual file structure of packages/api directory">
  <img src="https://mintcdn.com/cartanova-7788888c/mRzLpig-R41-Dqkz/images/projectStructure2.png?fit=max&auto=format&n=mRzLpig-R41-Dqkz&q=85&s=41b321dee49c0336e04de1bd3613331b" alt="packages/api directory structure" style={{ maxWidth: "500px", width: "100%", borderRadius: "0.75rem" }} width="770" height="734" data-path="images/projectStructure2.png" />
</Frame>

<Accordion title="Key File Descriptions">
  **package.json**

  * Backend dependency management
  * npm scripts: `dev`, `build`, `test`, `docker:up/down`, `dump`, `seed`, etc.

  **vitest.config.ts**

  * Vitest test configuration
  * Sonamu-optimized settings via `getSonamuTestConfig()` function
  * Coverage, reporter, sequencer configuration

  **tsconfig.json**

  * Main TypeScript compiler configuration
  * `tsconfig.schemas.json`: Dedicated for Zod schema generation
  * `tsconfig.types.json`: Dedicated for type definition generation

  **.env**

  * Database connection info (DB\_HOST, DB\_PORT, DB\_USER, DB\_PASSWORD)
  * Project configuration variables (DATABASE\_NAME, CONTAINER\_NAME, PROJECT\_NAME)
  * Auto-generated when running `pnpm create sonamu`
</Accordion>

### src/ Directory

<FileTree>
  <FileItem name="packages/api/src/">
    <FileItem name="index.ts" description="Server entry point" />

    <FileItem name="sonamu.config.ts" description="Sonamu configuration file" />

    <FileItem name="application/" description="Per-entity folders (auto-generated)">
      <FileItem name="{entity}/">
        <FileItem name="{entity}.entity.json" description="Entity definition" />

        <FileItem name="{entity}.model.ts" description="Business logic" />

        <FileItem name="{entity}.types.ts" description="Types + Zod schemas" />

        <FileItem name="{entity}.model.test.ts" description="Tests (optional)" />
      </FileItem>

      <FileItem name="sonamu.generated.ts" description="Base schemas (auto-generated)" />
    </FileItem>

    <FileItem name="i18n/" description="Internationalization">
      <FileItem name="ko.ts" description="Korean translations" />

      <FileItem name="en.ts" description="English translations" />
    </FileItem>

    <FileItem name="migrations/" description="DB migration files" />

    <FileItem name="testing/" description="Test configuration">
      <FileItem name="global.ts" description="Global test setup" />

      <FileItem name="fixture.ts" description="Fixture management" />

      <FileItem name="setup-mocks.ts" description="Mock setup" />
    </FileItem>

    <FileItem name="typings/" description="Type definitions">
      <FileItem name="sonamu.d.ts" description="Sonamu global types" />

      <FileItem name="fastify.d.ts" description="Fastify extension types" />
    </FileItem>

    <FileItem name="utils/" description="Utility functions">
      <FileItem name="subset-loaders.ts" description="Subset loaders" />
    </FileItem>
  </FileItem>
</FileTree>

<Frame caption="packages/api/src directory structure (with application folder expanded)">
  <img src="https://mintcdn.com/cartanova-7788888c/mRzLpig-R41-Dqkz/images/projectStructure3.png?fit=max&auto=format&n=mRzLpig-R41-Dqkz&q=85&s=3ccccbc86fb39b2b8de881e49f0e6e74" alt="packages/api/src directory structure" style={{ maxWidth: "500px", width: "100%", borderRadius: "0.75rem" }} width="798" height="900" data-path="images/projectStructure3.png" />
</Frame>

<Note>
  **Entity File Creation Process**

  Files in the `application/{entity}/` folder are created when you create an entity through Sonamu UI and scaffold:

  * **{entity}.entity.json**: Auto-generated when defining entity in Sonamu UI
  * **{entity}.model.ts**: Generated via `pnpm scaffold model` or Sonamu UI's Scaffolding tab
  * **{entity}.types.ts**: Auto-generated when saving entity
  * **{entity}.model.test.ts**: Generated via `pnpm scaffold model_test` or Sonamu UI's Scaffolding tab (optional)

  When you first create a project, the `application/` folder is empty. The folder is created when you create your first entity.
</Note>

<Accordion title="Key Directory Descriptions">
  **application/**

  * Auto-created when creating the first entity
  * Separate directory for each entity
  * Example: `User` entity → `application/user/` directory

  **application/{entity}/{entity}.entity.json**

  * Entity definition file
  * Created in Sonamu UI
  * Source of database schema

  **application/{entity}/{entity}.model.ts**

  * Business logic implementation
  * API endpoint definitions (`@api` decorator)
  * File you write directly

  **application/{entity}/{entity}.types.ts**

  * TypeScript type definitions
  * Zod validation schemas
  * Auto-generated but extensible
  * Shared with frontend

  **application/sonamu.generated.ts**

  * Auto-generated Base schemas for all entities
  * Enum types and label definitions
  * Do not modify directly

  **i18n/**

  * Internationalization translation files
  * `ko.ts`: Korean, `en.ts`: English
  * `sd.generated.ts` is auto-generated when adding entities

  **migrations/**

  * DB migration files generated by Sonamu UI
  * Run with `pnpm sonamu migrate run`

  **testing/**

  * Vitest test environment configuration
  * `global.ts`: Uses `export { setup } from "sonamu/test"` pattern
  * Fixture data management
</Accordion>

<Info>
  **Learn More - Entity Files** - [Defining Entities](/en/core-concepts/entity/defining-entities) -
  How to write entity.json - [Creating Models](/en/core-concepts/model/creating-models) - model.ts
  writing guide - [Type System](/en/core-concepts/type-system/entity-types) - Understanding types.ts

  * [What Gets Generated](/en/core-concepts/auto-generation/what-gets-generated) - Which files are
    auto-generated - [Writing Tests](/en/testing/writing-tests/test-structure) - Test file structure
</Info>

### database/ Directory

<FileTree>
  <FileItem name="packages/api/database/">
    <FileItem name="docker-compose.yml" description="PostgreSQL container configuration" />

    <FileItem name="fixtures/">
      <FileItem name="init.sh" description="Database initialization script" />
    </FileItem>

    <FileItem name="dumps/" description="Data dump files" />

    <FileItem name="scripts/">
      <FileItem name="dump.sh" description="Data backup script" />

      <FileItem name="seed.sh" description="Data restore script" />
    </FileItem>
  </FileItem>
</FileTree>

<Accordion title="Key File Descriptions">
  **docker-compose.yml**

  * PostgreSQL + pgvector image
  * Container name, port, environment variable configuration
  * Run with `pnpm docker:up`

  **fixtures/init.sh**

  * Database initialization shell script
  * Installs pgvector extension and creates databases
  * Creates databases using environment variables (`DATABASE_NAME`, `_fixture`, `_test`)
  * Auto-generated when running `pnpm create sonamu`

  **dumps/**

  * SQL files generated by `pnpm dump` command
  * Data backup storage

  **scripts/**

  * `dump.sh`: Backs up current DB data to dumps/
  * `seed.sh`: Restores data from dumps/ to DB
</Accordion>

<Info>
  **Learn More - Configuration Files** - [sonamu.config.ts
  Settings](/en/configuration/sonamu-config/project-settings) - Overall project configuration -
  [Database Configuration](/en/configuration/sonamu-config/database) - DB connection and settings -
  [Server Configuration](/en/configuration/sonamu-config/server) - Fastify server settings -
  [TypeScript Configuration](/en/configuration/typescript/tsconfig) - Compiler options -
  [Environment Variables](/en/configuration/environment-variables/env-setup) - .env file management
</Info>

## Web Directory (Frontend)

### Root Files

<FileTree>
  <FileItem name="packages/web/">
    <FileItem name="src/" description="Source code" />

    <FileItem name="index.html" description="HTML entry point" />

    <FileItem name="package.json" description="Dependencies and scripts" />

    <FileItem name="vite.config.ts" description="Vite configuration" />

    <FileItem name="tailwind.config.ts" description="Tailwind CSS configuration" />

    <FileItem name="tsconfig.json" description="TypeScript configuration" />

    <FileItem name="tsconfig.node.json" description="Node environment config" />

    <FileItem name=".sonamu.env" description="Environment variables" />
  </FileItem>
</FileTree>

<Frame caption="Actual file structure of packages/web directory">
  <img src="https://mintcdn.com/cartanova-7788888c/wk-O_9zBoKGthXNV/images/projectStructure4.png?fit=max&auto=format&n=wk-O_9zBoKGthXNV&q=85&s=d1d95f5795967fae93683d700226e3ae" alt="packages/web directory structure" style={{ maxWidth: "500px", width: "100%", borderRadius: "0.75rem" }} width="848" height="644" data-path="images/projectStructure4.png" />
</Frame>

<Accordion title="Key File Descriptions">
  **vite.config.ts**

  * Vite development server configuration
  * TanStack Router, Tailwind CSS v4, unplugin-icons plugins
  * API proxy settings (`/api` → `http://localhost:34900`)
  * SSR configuration included

  **tailwind.config.ts**

  * Tailwind CSS v4 configuration

  **.sonamu.env**

  * API server connection information
  * `API_HOST`, `API_PORT` settings
</Accordion>

### src/ Directory

<FileTree>
  <FileItem name="packages/web/src/">
    <FileItem name="entry-client.tsx" description="Client entry point" />

    <FileItem name="entry-server.generated.tsx" description="SSR entry point (auto-generated)" />

    <FileItem name="App.tsx" description="Root component" />

    <FileItem name="routeTree.gen.ts" description="Route tree (auto-generated)" />

    <FileItem name="routes/" description="TanStack Router based pages">
      <FileItem name="__root.tsx" description="Root layout" />

      <FileItem name="index.tsx" description="Home page" />
    </FileItem>

    <FileItem name="services/" description="API services (auto-generated)">
      <FileItem name="{entity}/" description="Per-entity services">
        <FileItem name="{entity}.service.ts" />
      </FileItem>

      <FileItem name="sonamu.generated.ts" />

      <FileItem name="sonamu.shared.ts" />

      <FileItem name="services.generated.ts" />
    </FileItem>

    <FileItem name="contexts/" description="React Context">
      <FileItem name="SonamuContext.tsx" description="Sonamu Provider" />
    </FileItem>

    <FileItem name="i18n/" description="Internationalization">
      <FileItem name="ko.ts" />

      <FileItem name="en.ts" />
    </FileItem>

    <FileItem name="admin-common/" description="Common components">
      <FileItem name="ApiLogViewer.tsx" />
    </FileItem>

    <FileItem name="components/" description="UI components" />

    <FileItem name="styles/" description="Style files" />

    <FileItem name="vite-env.d.ts" description="Vite type definitions" />
  </FileItem>
</FileTree>

<Accordion title="Key Directory Descriptions">
  **routes/**

  * TanStack Router based file system routing
  * `__root.tsx`: Global layout
  * Filenames map to URL paths

  **services/**

  * Service layer for communicating with the API server
  * Auto-generated for each entity
  * TanStack Query integration support

  **contexts/**

  * React Context Providers
  * SonamuContext: Global state management

  **i18n/**

  * Frontend internationalization translation files
  * Synchronized with API's i18n

  **admin-common/**

  * Reusable common components
  * Debugging tools like ApiLogViewer
</Accordion>

<Info>
  **Learn More - Frontend** - [How Services
  Work](/en/frontend-integration/generated-services/how-services-work) - Auto-generation mechanism -
  [Using Services](/en/frontend-integration/generated-services/using-services) - How to call APIs -
  [Shared Types](/en/frontend-integration/type-safety/shared-types) - Backend-frontend type
  synchronization
</Info>

## Example File Structure After Creating an Entity

When you create a User entity, the following structure is created:

<FileTree>
  <FileItem name="packages/api/src/application/">
    <FileItem name="user/">
      <FileItem name="user.entity.json" description="Created in Sonamu UI" />

      <FileItem name="user.model.ts" description="Manually written" />

      <FileItem name="user.types.ts" description="Auto-generated (extensible)" />

      <FileItem name="user.model.test.ts" description="Manually written (optional)" />
    </FileItem>

    <FileItem name="sonamu.generated.ts" description="Auto-updated" />
  </FileItem>

  <FileItem name="packages/api/src/migrations/">
    <FileItem name="20250106120000_create_user.sql" description="Auto-generated" />
  </FileItem>

  <FileItem name="packages/web/src/services/">
    <FileItem name="user/">
      <FileItem name="user.service.ts" description="Auto-generated" />
    </FileItem>
  </FileItem>
</FileTree>

<Frame caption="Actual file structure of packages/api/src/application/user folder after creating User entity">
  <div className="grid grid-cols-2 gap-4">
    <img src="https://mintcdn.com/cartanova-7788888c/wk-O_9zBoKGthXNV/images/projectStructure5.png?fit=max&auto=format&n=wk-O_9zBoKGthXNV&q=85&s=0f108de31a0c15a13b4140ab0854b8a7" alt="user folder structure 1" style={{ borderRadius: "0.75rem" }} width="856" height="958" data-path="images/projectStructure5.png" />

    <img src="https://mintcdn.com/cartanova-7788888c/wk-O_9zBoKGthXNV/images/projectStructure6.png?fit=max&auto=format&n=wk-O_9zBoKGthXNV&q=85&s=418803499200af1bc8226514ee0a925a" alt="user folder structure 2" style={{ borderRadius: "0.75rem" }} width="838" height="1108" data-path="images/projectStructure6.png" />
  </div>
</Frame>

### Role of Each File

<CodeGroup>
  ```json title="user.entity.json" theme={null}
  {
    "properties": [
      {
        "name": "id",
        "type": "int",
        "isPrimary": true
      },
      {
        "name": "email",
        "type": "varchar"
      },
      {
        "name": "name",
        "type": "varchar"
      }
    ]
  }
  ```

  ```typescript title="user.model.ts" theme={null}
  // File you write directly
  import { api, BaseModelClass } from "sonamu";

  class UserModelClass extends BaseModelClass {
    @api({ httpMethod: "GET", clients: ["axios", "tanstack-query"] })
    async findById(id: number): Promise<UserSubsetA | null> {
      // Business logic
    }
  }

  export const UserModel = new UserModelClass();
  ```

  ```typescript title="user.types.ts" theme={null}
  // Auto-generated + extensible
  import { z } from "zod";
  import { UserBaseSchema } from "../sonamu.generated";

  // Base type (auto-generated)
  export type User = z.infer<typeof UserBaseSchema>;

  // Extensible custom types
  export const UserSaveParams = UserBaseSchema.partial({
    id: true,
    created_at: true,
  });
  export type UserSaveParams = z.infer<typeof UserSaveParams>;
  ```

  ```typescript title="sonamu.generated.ts" theme={null}
  // Auto-generated - do not modify directly
  export const UserBaseSchema = z.object({
    id: z.number(),
    email: z.string(),
    name: z.string(),
    created_at: z.date(),
  });

  export const UserOrderBy = z.enum(["id-desc", "name-asc"]);
  export type UserOrderBy = z.infer<typeof UserOrderBy>;
  ```

  ```typescript title="user.service.ts (web)" theme={null}
  // Auto-generated
  import { useQuery } from "@tanstack/react-query";

  export class UserService {
    static async findById(id: number): Promise<UserSubsetA | null> {
      const res = await axios.get(`/api/user/findById`, { params: { id } });
      return res.data;
    }

    // TanStack Query hooks are also auto-generated
    static useFindById(id: number) {
      return useQuery({
        queryKey: ["User", "findById", id],
        queryFn: () => UserService.findById(id),
      });
    }
  }
  ```
</CodeGroup>

<Frame caption="VS Code screen with user.entity.json, user.model.ts, user.types.ts files open side by side (split view)">
  <img src="https://mintcdn.com/cartanova-7788888c/wk-O_9zBoKGthXNV/images/projectStructure7.png?fit=max&auto=format&n=wk-O_9zBoKGthXNV&q=85&s=a2cfa0a6198a19e4c598ff99be14a0a3" alt="VS Code split view" style={{ width: "100%", borderRadius: "0.75rem" }} width="5004" height="1876" data-path="images/projectStructure7.png" />
</Frame>

<Note>
  **Auto-generated vs Manually Written** - `.entity.json`: Written in Sonamu UI - `.model.ts`:
  Manually written - `.types.ts`: Auto-generated but extensible - `sonamu.generated.ts`:
  Auto-generated - do not modify - `{entity}.service.ts`: Auto-generated - do not modify
</Note>

<Info>
  **Learn More - Per-File Guides** - [Defining Entities](/en/core-concepts/entity/defining-entities)

  * How to write entity.json - [@api Decorator](/en/core-concepts/model/api-decorator) - Defining
    APIs in model.ts - [Entity Types](/en/core-concepts/type-system/entity-types) - Using types.ts -
    [Generated Types](/en/core-concepts/type-system/generated-types) - Understanding
    sonamu.generated.ts
</Info>

## Key Work Locations During Development

| Task              | Location                                                       | Method           |
| ----------------- | -------------------------------------------------------------- | ---------------- |
| Entity Definition | `packages/api/src/application/{entity}/{entity}.entity.json`   | Sonamu UI        |
| Business Logic    | `packages/api/src/application/{entity}/{entity}.model.ts`      | Manual writing   |
| Custom Types      | `packages/api/src/application/{entity}/{entity}.types.ts`      | Manual extension |
| API Endpoints     | `@api` decorator in Model file                                 | Manual writing   |
| Database Config   | `packages/api/src/sonamu.config.ts`                            | Manual writing   |
| Server Config     | `packages/api/src/sonamu.config.ts`                            | Manual writing   |
| Writing Tests     | `packages/api/src/application/{entity}/{entity}.model.test.ts` | Manual writing   |
| Page Components   | `packages/web/src/routes/`                                     | Manual writing   |
| Common Components | `packages/web/src/admin-common/`                               | Manual writing   |

<Warning>
  **Auto-generated File Cautions** - `sonamu.generated.ts`: Never modify - `{entity}.service.ts`:
  Never modify - `{entity}.types.ts`: Extension is possible but do not modify auto-generated parts
</Warning>

## Next Steps

Now that you understand the project structure, create your first entity:

<CardGroup cols={2}>
  <Card title="Creating Your First Entity" icon="database" href="/en/getting-started/first-entity">
    Use Sonamu UI to create your first entity and define the database schema.
  </Card>

  <Card title="Development Workflow" icon="diagram-project" href="/en/getting-started/development-workflow">
    Understand Sonamu's complete development cycle and learn how to work efficiently.
  </Card>
</CardGroup>
