Twenty CRM Architecture: Essential Source Files for the NestJS and React Codebase

To understand Twenty CRM's architecture, examine packages/twenty-server/src/main.ts for the server bootstrap, app.module.ts for the root NestJS module, and packages/twenty-front/src/index.tsx with App.tsx for the React frontend entry points.

Twenty CRM is a modern, open-source customer relationship management platform structured as a TypeScript monorepo combining a NestJS backend with a React frontend. Navigating this codebase requires familiarity with specific entry-point files that wire together the GraphQL API, ORM layers, and UI components. This guide identifies the critical source files that define Twenty CRM's architecture and explains how they orchestrate the application's runtime behavior.

Backend Architecture: NestJS Entry Points

The backend follows a modular NestJS pattern where dependency injection and module imports define the application structure.

Server Bootstrap (main.ts)

The file packages/twenty-server/src/main.ts serves as the canonical entry point for the backend runtime. It creates a NestExpressApplication, registers global middleware, and mounts the GraphQL upload endpoints.

// packages/twenty-server/src/main.ts
import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
import { graphqlUploadExpress } from 'graphql-upload-ts';
import { AppModule } from './app.module';
import { generateFrontConfig } from './generate-front-config';

const bootstrap = async () => {
  const app = await NestFactory.create<NestExpressApplication>(AppModule, {
    cors: true,
    bufferLogs: process.env.LOGGER_IS_BUFFER_ENABLED === 'true',
  });

  // Session storage and global exception filters
  app.use(session(getSessionStorageOptions(twentyConfigService)));
  app.useGlobalFilters(new UnhandledExceptionFilter());

  // GraphQL file upload endpoints
  app.use('/graphql', graphqlUploadExpress({ maxFieldSize: …, maxFiles: 10 }));
  app.use('/metadata', graphqlUploadExpress({ maxFieldSize: …, maxFiles: 10 }));

  // Inject runtime configuration for the frontend
  generateFrontConfig();

  await app.listen(twentyConfigService.get('NODE_PORT'));
};
bootstrap();

Key insight: This file handles all runtime configuration including SSL termination, session management via getSessionStorageOptions, and the injection of server-side configuration into the frontend through generateFrontConfig().

Root Module (app.module.ts)

Located at packages/twenty-server/src/app.module.ts, the root module imports the entire infrastructure stack and conditionally serves static assets.

// packages/twenty-server/src/app.module.ts
@Module({
  imports: [
    SentryModule.forRoot(),
    GraphQLModule.forRootAsync<YogaDriverConfig>({ … }),
    TwentyORMModule,
    ClickHouseModule,
    CoreEngineModule,          // Business logic aggregation
    ModulesModule,            // Generated feature modules
    WorkspaceCacheStorageModule,
    // API surface modules
    CoreGraphQLApiModule,
    MetadataGraphQLApiModule,
    RestApiModule,
    McpModule,
    DataSourceModule,
    // Conditional static asset serving
    ...AppModule.getConditionalModules(),
  ],
})
export class AppModule {}

The ServeStaticModule (returned by getConditionalModules()) serves the compiled React application from packages/twenty-server/front when running in production mode.

Core Engine Module (core-engine.module.ts)

The heart of Twenty CRM's backend resides in packages/twenty-server/src/engine/core-modules/core-engine.module.ts. This module aggregates all domain-specific capabilities.

// packages/twenty-server/src/engine/core-modules/core-engine.module.ts
@Module({
  imports: [
    EnvironmentModule,
    TwentyConfigModule.forRoot(),
    HealthModule,
    AuditModule,
    AuthModule,
    BillingModule,
    FeatureFlagModule,
    WorkflowModule,
    AiModule,
    // Infrastructure utilities
    RedisClientModule,
    MessageQueueModule.registerAsync({ … }),
    LoggerModule.forRootAsync({ … }),
    WorkspaceModule,
    WorkspaceInvitationModule,
    WorkspaceSSOModule,
  ],
  exports: [
    AuthModule,
    UserModule,
    WorkspaceModule,
    FeatureFlagModule,
    TimelineMessagingModule,
    ImapSmtpCaldavModule,
  ],
})
export class CoreEngineModule {}

Architectural note: By centralizing feature modules like AuthModule, BillingModule, and AiModule within CoreEngineModule, Twenty CRM maintains clear dependency boundaries while allowing specific modules to be exported for reuse across the application.

Frontend Architecture: React and State Management

The frontend follows a single-page application (SPA) pattern with Jotai for state management and Apollo Client for GraphQL communication.

SPA Entry Point (index.tsx)

The file packages/twenty-front/src/index.tsx creates the React root and mounts the application.

// packages/twenty-front/src/index.tsx
import ReactDOM from 'react-dom/client';
import { App } from '@/app/components/App';
import 'react-loading-skeleton/dist/skeleton.css';
import 'twenty-ui/style.css';
import 'twenty-ui/theme-light.css';
import 'twenty-ui/theme-dark.css';
import './index.css';

const root = ReactDOM.createRoot(document.getElementById('root') ?? document.body);
root.render(<App />);

This entry point loads global stylesheets from the twenty-ui design system before rendering the root component.

Root Component (App.tsx)

Located at packages/twenty-front/src/modules/app/components/App.tsx, this component configures the provider hierarchy essential to Twenty CRM's frontend architecture.

// packages/twenty-front/src/modules/app/components/App.tsx
import { Provider as JotaiProvider } from 'jotai';
import { ApolloProvider } from '@apollo/client';
import { LinguiProvider } from '@lingui/react';
import { client } from '@/app/apollo';
import { AppLayout } from '@/app/components/layout/AppLayout';
import { FrontConfigProvider } from '@/front-config/FrontConfigProvider';
import { i18n } from '@/i18n';

export function App() {
  return (
    <JotaiProvider>
      <ApolloProvider client={client}>
        <LinguiProvider i18n={i18n}>
          <FrontConfigProvider>
            <AppLayout />
          </FrontConfigProvider>
        </LinguiProvider>
      </ApolloProvider>
    </JotaiProvider>
  );
}

Provider stack:

  • JotaiProvider: Global state management for atoms
  • ApolloProvider: GraphQL client configured in src/app/apollo
  • LinguiProvider: Internationalization (i18n) support
  • FrontConfigProvider: Consumes the configuration generated by the backend's generateFrontConfig(), providing API base URLs and feature flags

Data Flow and Integration Points

Understanding Twenty CRM's architecture requires tracing how data moves between these entry points:

  • HTTP Request Flow: Requests hit the NestJS server via main.ts, route through middleware (session, CORS), and reach controllers or GraphQL resolvers defined in CoreGraphQLApiModule and MetadataGraphQLApiModule.
  • GraphQL Schema Generation: The backend schema is configured in packages/twenty-server/src/engine/api/graphql/graphql-config/graphql-config.module.ts, which defines type definitions and resolvers.
  • Frontend Type Generation: GraphQL types are auto-generated into packages/twenty-front/src/generated-metadata/, ensuring type safety between the backend schema and frontend queries.
  • Authentication Flow: AuthModule (backend) validates JWT/cookie sessions, while useAuth Jotai atoms (frontend) manage authentication state.
  • Shared Types: The packages/twenty-shared/ directory contains TypeScript interfaces and constants used by both frontend and backend packages.

Practical Code Examples

Starting the Development Environment

Use the Nx CLI to start both layers of the Twenty CRM architecture:


# Terminal 1: Start the NestJS backend

npx nx start twenty-server

# Terminal 2: Start the React frontend (Vite dev server)

npx nx start twenty-front

Adding a New Backend Feature

To extend the Twenty CRM architecture with new business logic:

// packages/twenty-server/src/modules/example/example.module.ts
import { Module } from '@nestjs/common';
import { ExampleService } from './example.service';
import { ExampleController } from './example.controller';

@Module({
  providers: [ExampleService],
  controllers: [ExampleController],
})
export class ExampleModule {}

Then register it in the Core Engine:

// packages/twenty-server/src/engine/core-modules/core-engine.module.ts
import { ExampleModule } from 'src/modules/example/example.module';

@Module({
  imports: [
    // ... existing imports
    ExampleModule,
  ],
})
export class CoreEngineModule {}

Consuming GraphQL in React Components

Frontend components consume the auto-generated schema through Apollo Client:

// packages/twenty-front/src/pages/settings/profile/SettingsProfile.tsx
import { gql, useQuery } from '@apollo/client';
import { t } from '@lingui/macro';

const USER_PROFILE = gql`
  query GetUserProfile {
    me {
      id
      name
      email
    }
  }
`;

export function SettingsProfile() {
  const { data, loading, error } = useQuery(USER_PROFILE);
  
  if (loading) return <Spinner />;
  if (error) return <ErrorMessage error={error} />;

  return (
    <section>
      <h2>{t`Profile`}</h2>
      <p>{data.me.name} &lt;{data.me.email}&gt;</p>
    </section>
  );
}

Summary

Frequently Asked Questions

What technology stack powers Twenty CRM?

Twenty CRM utilizes NestJS for the backend API and React with Jotai for the frontend state management. The system uses GraphQL for API communication, TypeORM (via TwentyORM) for database operations, and ClickHouse for analytics data. The entire codebase is written in TypeScript and organized as a monorepo.

How does the backend serve the frontend application?

According to the source code in packages/twenty-server/src/app.module.ts, the backend conditionally registers a ServeStaticModule when it detects a compiled frontend build in the front directory. Additionally, main.ts calls generateFrontConfig() to inject runtime variables such as API base URLs and feature flags into the frontend's FrontConfigProvider.

Where is the GraphQL schema configured in Twenty CRM?

The GraphQL server configuration is defined in packages/twenty-server/src/engine/api/graphql/graphql-config/graphql-config.module.ts. This module configures the Yoga driver, type definitions, resolvers, and authentication guards for both the core application API and the metadata API endpoints mounted in main.ts.

How can I add a new feature module to Twenty CRM?

Create your module in packages/twenty-server/src/modules/, then import it into CoreEngineModule at packages/twenty-server/src/engine/core-modules/core-engine.module.ts. This registration makes your feature part of the core engine architecture, allowing it to access shared utilities like the message queue, cache storage, and configuration services.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →