c26c0b9d71
## Summary - **SDK (`dev` & `dev --once`)**: After app registration, the CLI now obtains an `APPLICATION_ACCESS` token via `client_credentials` grant using the app's own `clientId`/`clientSecret`, and uses that token for CoreApiClient schema introspection — instead of the user's `config.accessToken` which returns the full unscoped schema. - **Config**: `oauthClientSecret` is now persisted alongside `oauthClientId` in `~/.twenty/config.json` when creating a new app registration, so subsequent `dev`/`dev --once` runs can obtain fresh app tokens without re-registration. - **CI action**: `spawn-twenty-app-dev-test` now outputs a proper `API_KEY` JWT (signed with the seeded dev workspace secret) instead of the previous hardcoded `ACCESS` token — giving consumers a real API key rather than a user session token. ## Motivation When developing Twenty apps, `yarn twenty dev` was using the CLI user's OAuth token for GraphQL schema introspection during CoreApiClient generation. This token (type `ACCESS`) has no `applicationId` claim, so the server returns the **full workspace schema** — including all objects — rather than the scoped schema the app should see at runtime (filtered by `applicationId`). This caused a discrepancy: the generated CoreApiClient contained fields the app couldn't actually query at runtime with its `APPLICATION_ACCESS` token. By switching to `client_credentials` grant, the SDK now introspects with the same token type the app will use in production, ensuring the generated client accurately reflects the app's runtime capabilities.
The official scaffolding CLI for building apps on top of Twenty CRM. Sets up a ready-to-run project with twenty-sdk.
Quick start
npx create-twenty-app@latest my-twenty-app
cd my-twenty-app
yarn twenty dev
The scaffolder will:
- Create a new project with TypeScript, linting, tests, and a preconfigured
twentyCLI - Optionally start a local Twenty server (Docker)
- Open the browser for OAuth authentication
Options
| Flag | Description |
|---|---|
--example <name> |
Initialize from an example |
--name <name> |
Set the app name (skips the prompt) |
--display-name <displayName> |
Set the display name (skips the prompt) |
--description <description> |
Set the description (skips the prompt) |
--skip-local-instance |
Skip the local server setup prompt |
By default (no flags), a minimal app is generated with core files and an integration test. Use --example to start from a richer example:
npx create-twenty-app@latest my-twenty-app --example hello-world
Examples are sourced from twentyhq/twenty/packages/twenty-apps/examples.
Documentation
Full documentation is available at docs.twenty.com/developers/extend/apps:
- Getting Started — step-by-step setup, project structure, server management, CI
- Building Apps — entity definitions, API clients, testing
- Publishing — deploy, npm publish, marketplace
Troubleshooting
- Server not starting: check Docker is running (
docker info), then tryyarn twenty server logs. - Auth not working: make sure you are logged in to Twenty in the browser, then run
yarn twenty remote add. - Types not generated: ensure
yarn twenty devis running — it auto-generates the typed client.