Skip to main content

Overview

A new app generated by twenty app init looks like this:

Key files

File organization is up to you. The folders above are conventions — the CLI detects entities via AST analysis on export default defineEntity(...) calls regardless of where the file lives.

Dependencies

twenty app init puts twenty-sdk, twenty-client-sdk, and twenty-ui under devDependencies, pinned to the SDK version selected by that CLI release. Keep the generated versions for a new app and keep all three packages in sync when upgrading. The CLI can receive patch releases independently, so its version need not match these packages. The generated engines.twenty sets the minimum server version to that SDK’s major and minor release. The generated GitHub Actions workflows pin the CLI separately.
  • twenty-sdk provides app definitions, runtime helpers, and renderer integration. Use the separately installed twenty package for CLI commands and build/scaffolding tooling.
  • twenty-client-sdk is imported by your app code (CoreApiClient, MetadataApiClient, RestApiClient), but Twenty provides it at runtime — logic functions get it from a generated SDK layer, and front components resolve it from server-served modules. Your installed copy is only used for typechecking and the deploy-time build, so it never needs to ship in the deployed bundle.
Keeping either package under dependencies pulls it into the installed app’s runtime bundle, where it is dead weight. twenty app build emits a warning when either is still listed under dependencies. Add your app’s own runtime dependencies (libraries your logic functions actually import at runtime) under dependencies as usual. Keep the tree lean: dependencies are installed into a runtime layer capped at 250MB unpacked, and a sync or install fails with a dependencies size error beyond that — UI libraries and dev tooling belong in devDependencies.