Files
twenty/packages/create-twenty-app
Félix MalfaitGitHubclaude[bot] <41898282+claude[bot]@users.noreply.github.com>
012d819557 OAuth Client — Unified ApplicationRegistration, OAuth server, and frontend (#18267)
## Summary

Consolidates three separate PRs (#18260, #18261, #18262) into a single
unified branch with all review feedback addressed:

### New features
- **ApplicationRegistration entity** — server-level registration for
OAuth apps with encrypted server variables
- **OAuth 2.0 server** — authorization code, client credentials, refresh
token grants with PKCE support
- **OAuth discovery endpoint** —
`.well-known/oauth-authorization-server` metadata
- **Frontend UI** — app registration details page with credential
management, redirect URI editing, and server variable configuration
- **CLI integration** — `twenty dev` auto-registers apps and stores
OAuth credentials locally
- **Authorize consent screen** — OAuth consent page at `/authorize`
showing requested scopes

### Review feedback addressed

**Renames (PR #18260):**
- `appRegistration` → `applicationRegistration` (entity, tables, files,
imports, GraphQL types)
- `appRegistrationVariable` → `applicationRegistrationVariable`
- `clientId` → `oAuthClientId`, `clientSecretHash` →
`oAuthClientSecretHash`, `redirectUris` → `oAuthRedirectUris`, `scopes`
→ `oAuthScopes`

**Security fixes (PR #18261):**
- Fixed redirect URI validation bypass when `oAuthRedirectUris` is an
empty array
- Fixed workspace isolation in `clientCredentialsGrant` — now uses
`find()` with explicit handling for multiple installations
- Added error logging in refresh token `catch` block instead of silently
swallowing

**Code quality (PR #18262):**
- Split `VersionDistributionEntry` into its own file (one export per
file)
- Split GraphQL queries and mutations into individual files with a
shared fragment
- Removed unused `OAuth` entry from `AuthProviderEnum`
- Added loading state to `handleRotateSecret`
- Removed 27 narration-style comments from test files
- Added proper guards (`PublicEndpointGuard`, `NoPermissionGuard`) to
controllers and resolvers

## Test plan

- [ ] Verify `twenty dev` registers an app and stores OAuth credentials
- [ ] Test OAuth authorization code flow end-to-end (authorize → token →
API call)
- [ ] Test client credentials grant
- [ ] Verify redirect URI validation rejects requests when no URIs are
registered
- [ ] Verify app registration detail page renders correctly
- [ ] Test secret rotation with loading state
- [ ] Verify server variable editing and saving
- [ ] Run `npx nx database:reset twenty-server` to validate migration

Closes #18260, #18261, #18262


Made with [Cursor](https://cursor.com)

---------

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
2026-02-28 14:07:49 +01:00
..
2026-02-25 10:35:46 +01:00
2026-02-05 14:25:49 +01:00

Twenty logo

Create Twenty App

NPM version License Join the community on Discord

Create Twenty App is the official scaffolding CLI for building apps on top of Twenty CRM. It sets up a readytorun project that works seamlessly with the twenty-sdk.

  • Zeroconfig project bootstrap
  • Preconfigured scripts for auth, dev mode (watch & sync), uninstall, and function management
  • Strong TypeScript support and typed client generation

Documentation

See Twenty application documentation https://docs.twenty.com/developers/extend/capabilities/apps

Prerequisites

Quick start

npx create-twenty-app@latest my-twenty-app
cd my-twenty-app

# Get help and list all available commands
yarn twenty help

# Authenticate using your API key (you'll be prompted)
yarn twenty auth:login

# Add a new entity to your application (guided)
yarn twenty entity:add

# Start dev mode: watches, builds, and syncs local changes to your workspace
# (also auto-generates typed API clients — CoreApiClient and MetadataApiClient — in node_modules/twenty-sdk/generated)
yarn twenty app:dev

# Watch your application's function logs
yarn twenty function:logs

# Execute a function with a JSON payload
yarn twenty function:execute -n my-function -p '{"key": "value"}'

# Execute the pre-install function
yarn twenty function:execute --preInstall

# Execute the post-install function
yarn twenty function:execute --postInstall

# Uninstall the application from the current workspace
yarn twenty app:uninstall

Scaffolding modes

Control which example files are included when creating a new app:

Flag Behavior
-e, --exhaustive (default) Creates all example files without prompting
-m, --minimal Creates only core files (application-config.ts and default-role.ts)
-i, --interactive Prompts you to select which examples to include
# Default: all examples included
npx create-twenty-app@latest my-app

# Minimal: only core files
npx create-twenty-app@latest my-app -m

# Interactive: choose which examples to include
npx create-twenty-app@latest my-app -i

In interactive mode, you can pick from:

  • Example object — a custom CRM object definition (objects/example-object.ts)
  • Example field — a custom field on the example object (fields/example-field.ts)
  • Example logic function — a server-side handler with HTTP trigger (logic-functions/hello-world.ts)
  • Example front component — a React UI component (front-components/hello-world.tsx)
  • Example view — a saved view for the example object (views/example-view.ts)
  • Example navigation menu item — a sidebar link (navigation-menu-items/example-navigation-menu-item.ts)
  • Example skill — an AI agent skill definition (skills/example-skill.ts)

What gets scaffolded

Core files (always created):

  • application-config.ts — Application metadata configuration
  • roles/default-role.ts — Default role for logic functions
  • logic-functions/pre-install.ts — Pre-install logic function (runs before app installation)
  • logic-functions/post-install.ts — Post-install logic function (runs after app installation)
  • TypeScript configuration, ESLint, package.json, .gitignore
  • A prewired twenty script that delegates to the twenty CLI from twenty-sdk

Example files (controlled by scaffolding mode):

  • objects/example-object.ts — Example custom object with a text field
  • fields/example-field.ts — Example standalone field extending the example object
  • logic-functions/hello-world.ts — Example logic function with HTTP trigger
  • front-components/hello-world.tsx — Example front component
  • views/example-view.ts — Example saved view for the example object
  • navigation-menu-items/example-navigation-menu-item.ts — Example sidebar navigation link
  • skills/example-skill.ts — Example AI agent skill definition

Next steps

  • Run yarn twenty help to see all available commands.
  • Use yarn twenty auth:login to authenticate with your Twenty workspace.
  • Explore the generated project and add your first entity with yarn twenty entity:add (logic functions, front components, objects, roles, views, navigation menu items, skills).
  • Use yarn twenty app:dev while you iterate — it watches, builds, and syncs changes to your workspace in real time.
  • Two typed API clients are autogenerated by yarn twenty app:dev and stored in node_modules/twenty-sdk/generated: CoreApiClient (for workspace data via /graphql) and MetadataApiClient (for workspace configuration and file uploads via /metadata).

Publish your application

Applications are currently stored in twenty/packages/twenty-apps.

You can share your application with all Twenty users:

# pull the Twenty project
git clone https://github.com/twentyhq/twenty.git
cd twenty

# create a new branch
git checkout -b feature/my-awesome-app
git commit -m "Add new application"
git push

Our team reviews contributions for quality, security, and reusability before merging.

Troubleshooting

  • Auth prompts not appearing: run yarn twenty auth:login again and verify the API key permissions.
  • Types not generated: ensure yarn twenty app:dev is running — it autogenerates the typed client.

Contributing