twentyhq/twenty

Building a modern alternative to Salesforce, powered by the community.

44,745 stars TypeScript 8 components

Full-stack open-source CRM platform with React frontend, GraphQL API, and multi-tenant backend architecture

User interactions in the frontend trigger GraphQL queries via Apollo Client to the NestJS backend, which dynamically generates schemas from workspace metadata and executes operations against tenant-isolated databases. The backend can trigger email notifications through the email service and external automations via Zapier integrations. Configuration flows from environment variables and runtime detection in the frontend, while the UI component system provides consistent theming and accessibility.

Under the hood, the system uses 3 feedback loops, 3 data pools, 3 control points to manage its runtime behavior.

A 8-component fullstack. 16512 files analyzed. Data flows through 6 distinct pipeline stages.

How Data Flows Through the System

User interactions in the frontend trigger GraphQL queries via Apollo Client to the NestJS backend, which dynamically generates schemas from workspace metadata and executes operations against tenant-isolated databases. The backend can trigger email notifications through the email service and external automations via Zapier integrations. Configuration flows from environment variables and runtime detection in the frontend, while the UI component system provides consistent theming and accessibility.

  1. Frontend Initialization — The React app loads from index.tsx, initializes Apollo Client with the server URL from ConfigLoader, and establishes GraphQL communication channel with authentication context
  2. Schema Generation — WorkspaceSchemaBuilder reads workspace metadata from the database and dynamically creates GraphQL schemas with custom object types, field resolvers, and permission rules specific to each tenant [WorkspaceMetadata → GraphQLResponse]
  3. Object Operations — Frontend components execute GraphQL queries and mutations for CRM operations (creating contacts, updating deals, managing pipelines) which the backend processes through dynamically generated resolvers [GraphQLResponse → WorkspaceMetadata]
  4. Email Rendering — EmailRenderer transforms TipTap JSONContent templates with dynamic data into HTML emails for password resets, workspace invitations, and notification workflows [EmailTemplate → EmailTemplate]
  5. External Integration — ZapierApp exposes Twenty operations as Zapier triggers and actions, allowing users to create automated workflows between Twenty and 3000+ external applications [ZapierIntegration → ZapierIntegration]
  6. UI Rendering — React components consume Apollo Client data and render using the twenty-ui component library with accessibility support from VisibilityHidden and related utilities [UIComponent]

Data Models

The data structures that flow between stages — the contracts that hold the system together.

WorkspaceMetadata packages/twenty-server
Multi-tenant workspace configuration with dynamic object schemas, field definitions, permission settings, and custom business logic rules
Created during workspace setup, continuously modified through the metadata API as users customize objects and fields, cached for runtime schema generation
GraphQLResponse packages/twenty-front/src/config/index.ts
Apollo Client response objects with data, loading states, error information, and network status for all frontend-backend communication
Generated by Apollo Client from GraphQL queries, cached in Apollo cache, transformed into component props and Jotai atoms for reactive updates
EmailTemplate packages/twenty-emails/src/index.ts
TipTap JSONContent structure with rich text nodes, attributes, and marks for composing transactional email content
Defined as static templates, rendered with dynamic data to HTML, sent via email service providers
ZapierIntegration packages/twenty-zapier/src/index.ts
Zapier platform configuration with version, authentication schema, trigger definitions, and action handlers for third-party automation
Configured once per integration, executed dynamically when Zapier workflows trigger, maintains authentication tokens and rate limits
UIComponent packages/twenty-ui/src/accessibility/index.ts
React component props with accessibility attributes, theme tokens, and styling configurations following the design system
Instantiated during React rendering, styled with design tokens, managed through React lifecycle hooks and state

Hidden Assumptions

Things this code relies on but never validates. These are the things that cause silent failures when the system changes.

critical Environment unguarded

Assumes localhost development runs backend on port 3000 specifically, and production serves frontend and backend on the same port/protocol as the browser location

If this fails: If backend runs on different port in development or uses different protocol/port in production, GraphQL requests will fail with connection errors and the app won't load

packages/twenty-front/src/config/index.ts:getDefaultUrl
critical Domain unguarded

Assumes JWT tokens always have exactly 3 dot-separated parts and the payload is at index 1, encoded in base64url format

If this fails: If JWT format changes or malformed tokens exist, Buffer.from() will throw exceptions causing authentication to crash during testing

packages/twenty-e2e-testing/lib/utils/getAccessAuthToken.ts:decodePayload
critical Contract weakly guarded

Assumes DOM element with id 'root' exists in the HTML document, falling back to document.body if not found

If this fails: If neither root element nor document.body are available during SSR or in unusual environments, React rendering will fail silently or crash

packages/twenty-front/src/index.tsx:ReactDOM.createRoot
critical Shape unguarded

Assumes tokenPair cookie value contains a JSON object with accessOrWorkspaceAgnosticToken.token property structure

If this fails: If cookie structure changes or becomes corrupted, JSON.parse() or property access will throw errors, breaking authentication flow in tests

packages/twenty-e2e-testing/lib/utils/getAccessAuthToken.ts:decodeToken
warning Environment weakly guarded

Assumes window._env_ global variable or process.env are available and properly populated in browser environment

If this fails: In strict CSP environments or unusual deployment contexts, these variables might be undefined, causing fallback to potentially incorrect URL detection

packages/twenty-front/src/config/index.ts:REACT_APP_SERVER_BASE_URL
warning Ordering weakly guarded

Assumes githubStarsModel table contains at least one record when sorting by timestamp descending

If this fails: If table is empty, githubStars?.[0] will be undefined and numberOfStars will be undefined, potentially rendering empty star counts in header

packages/twenty-website/src/app/_components/ui/layout/header/index.tsx:findOne
warning Domain unguarded

Assumes localhost and 127.0.0.1 are the only development hostnames that need special port handling

If this fails: Custom development domains (like local.twenty.com) or Docker container names won't get port 3000 treatment, causing API connection failures

packages/twenty-front/src/config/index.ts:getDefaultUrl
warning Temporal unguarded

Assumes JWT tokens in cookies haven't expired and payload.type === 'ACCESS' identifies the correct token

If this fails: Expired tokens or mismatched token types will cause authentication failures in tests without clear error messages about token validity

packages/twenty-e2e-testing/lib/utils/getAccessAuthToken.ts:getAccessAuthToken
warning Resource unguarded

Assumes zapier-platform-core module is available and exports a version property at runtime

If this fails: If Zapier platform dependencies are missing or incompatible, the integration will fail to load with module resolution errors

packages/twenty-zapier/src/index.ts:platformVersion
info Contract unguarded

Assumes this file is always auto-generated and manual edits should never be made, but provides no enforcement mechanism

If this fails: Developers might manually edit this file not realizing it's auto-generated, causing their changes to be lost during the next generation cycle

packages/twenty-ui/src/accessibility/index.ts:auto-generated comment

System Behavior

How the system operates at runtime — where data accumulates, what loops, what waits, and what controls what.

Data Pools

Apollo Client Cache (cache)
Stores GraphQL query results and entity data for offline access and optimistic updates in the React frontend
Workspace Database (database)
Multi-tenant PostgreSQL database storing workspace metadata, custom objects, user data, and business records with tenant isolation
Component Registry (registry)
Exports React components with accessibility features and design system tokens for consistent UI rendering

Feedback Loops

Delays

Control Points

Technology Stack

React (framework)
Frontend framework for building the main CRM user interface with component-based architecture
Apollo Client (library)
GraphQL client managing API communication, caching, and state synchronization between frontend and backend
NestJS (framework)
Node.js framework powering the GraphQL API backend with dependency injection and modular architecture
GraphQL (framework)
API query language enabling dynamic schema generation and efficient data fetching for workspace customization
TypeScript (runtime)
Primary development language providing type safety across the entire monorepo codebase
Nx (build)
Monorepo build system managing package dependencies, caching, and development workflow across 19 packages
TipTap (library)
Rich text editor framework used in the email template system for creating structured content with JSONContent format
Zapier Platform (library)
Integration platform enabling workflow automation between Twenty and thousands of external applications

Key Components

Package Structure

twenty-front (app)
React-based web frontend providing the main CRM user interface with configurable views, forms, and workspace management
twenty-server (app)
Node.js/NestJS GraphQL API backend handling multi-tenant workspaces, data modeling, authentication, and business logic
twenty-emails (library)
Email template system and renderer for transactional emails like password resets and workspace invitations
twenty-ui (library)
React component library providing reusable UI components and design system tokens used across the platform
twenty-zapier (app)
Zapier integration adapter enabling workflow automation between Twenty and 3000+ external apps
twenty-utils (tooling)
Development utilities including Danger.js configurations for PR validation and contributor recognition
twenty-shared (shared)
Shared constants, types, and utilities used across multiple packages
twenty-website (app)
Marketing website built with Next.js showcasing product features and documentation
twenty-e2e-testing (tooling)
Playwright-based end-to-end testing suite for validating complete user workflows

Explore the interactive analysis

See the full architecture map, data flow, and code patterns visualization.

Analyze on CodeSea

Related Fullstack Repositories

Frequently Asked Questions

What is twenty used for?

Full-stack open-source CRM platform with React frontend, GraphQL API, and multi-tenant backend architecture twentyhq/twenty is a 8-component fullstack written in TypeScript. Data flows through 6 distinct pipeline stages. The codebase contains 16512 files.

How is twenty architected?

twenty is organized into 4 architecture layers: Frontend Layer, API Layer, Integration Layer, Shared Libraries. Data flows through 6 distinct pipeline stages. This layered structure keeps concerns separated and modules independent.

How does data flow through twenty?

Data moves through 6 stages: Frontend Initialization → Schema Generation → Object Operations → Email Rendering → External Integration → .... User interactions in the frontend trigger GraphQL queries via Apollo Client to the NestJS backend, which dynamically generates schemas from workspace metadata and executes operations against tenant-isolated databases. The backend can trigger email notifications through the email service and external automations via Zapier integrations. Configuration flows from environment variables and runtime detection in the frontend, while the UI component system provides consistent theming and accessibility. This pipeline design reflects a complex multi-stage processing system.

What technologies does twenty use?

The core stack includes React (Frontend framework for building the main CRM user interface with component-based architecture), Apollo Client (GraphQL client managing API communication, caching, and state synchronization between frontend and backend), NestJS (Node.js framework powering the GraphQL API backend with dependency injection and modular architecture), GraphQL (API query language enabling dynamic schema generation and efficient data fetching for workspace customization), TypeScript (Primary development language providing type safety across the entire monorepo codebase), Nx (Monorepo build system managing package dependencies, caching, and development workflow across 19 packages), and 2 more. A focused set of dependencies that keeps the build manageable.

What system dynamics does twenty have?

twenty exhibits 3 data pools (Apollo Client Cache, Workspace Database), 3 feedback loops, 3 control points, 3 delays. The feedback loops handle self-correction and cache-invalidation. These runtime behaviors shape how the system responds to load, failures, and configuration changes.

What design patterns does twenty use?

5 design patterns detected: Multi-Tenant Architecture, Metadata-Driven Development, Monorepo Package Isolation, Apollo Client State Management, Component Library Pattern.

Analyzed on April 20, 2026 by CodeSea. Written by .