docs(apps): align project structure and testing pages with the actual scaffold (#22690)

Part 3 of the app-docs audit series (after #22688 and #22689). Verified
by scaffolding a fresh app with `create-twenty-app` and diffing the docs
against the generated files and the template in
`packages/create-twenty-app/src/constants/template`.

## What this fixes

**getting-started/project-structure.mdx**
- The documented tree was missing most of what the scaffolder actually
generates: the starter welcome page (`front-components/`,
`navigation-menu-items/`, `page-layouts/`), the real test files
(`global-setup.ts`, `application-config.test.ts`,
`schema.integration-test.ts` — not `setup-test.ts` /
`app-install.integration-test.ts`), `cd.yml`, `vitest.unit.config.ts`,
and `AGENTS.md`/`CLAUDE.md` (the docs said `LLMS.md`, which isn't
generated).
- Dependency snippet showed `^2.13.0`; the scaffolder pins its own
version (currently 2.20.0) and also adds `twenty-ui`.
- `twenty build` → `twenty dev:build`.

**operations/testing.mdx**
- The Vitest setup section described a config that diverges from the
scaffold (uses `setupFiles` instead of `globalSetup`, writes the SDK
config to `os.tmpdir()/.twenty-sdk-test/config.json` — a path the CLI
never reads). Replaced with the actual pattern: `globalSetup` +
`~/.twenty/config.test.json` (what the CLI reads under `NODE_ENV=test`)
+ `appDevOnce` sync and uninstall-teardown.
- The CI section described a `spawn-twenty-docker-image` action and a
4-step workflow; the scaffolded `ci.yml` uses
`spawn-twenty-app-dev-test` and also runs lint, typecheck, and unit
tests. This section previously contradicted `operations/publishing.mdx`
— it now gives a short accurate summary and links to Publishing for the
full walkthrough of both workflows (de-duplicating the two pages).
- Added `appDevOnce` to the programmatic API table (used by the
scaffolded global setup).

**getting-started/troubleshooting.mdx**
- Node requirement made precise (`^24.5.0`), `twenty build` → `twenty
dev:build`.

Only English sources were touched; `l/<locale>` copies come from
Crowdin.

---
_Generated by [Claude
Code](https://claude.ai/code/session_01ExboyDAT19khDuKXaYXETT)_

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22690?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->

Co-authored-by: Martin <martin@twenty.com>
This commit is contained in:
martmull
2026-07-09 10:28:34 +02:00
committed by GitHub
parent 2781a06025
commit 0970f85cd2
3 changed files with 72 additions and 95 deletions
@@ -14,15 +14,26 @@ my-twenty-app/
default-role.ts # Permissions for logic functions
constants/
universal-identifiers.ts # Auto-generated UUIDs and metadata
front-components/
main-page.tsx # Welcome page component
navigation-menu-items/
main-page.navigation-menu-item.ts # Sidebar entry for the welcome page
page-layouts/
main-page.page-layout.ts # Standalone page hosting the component
__tests__/
setup-test.ts
app-install.integration-test.ts
.github/workflows/ci.yml # GitHub Actions
public/ # Static assets
vitest.config.ts # Test runner config
application-config.test.ts # Unit test
global-setup.ts # Integration test setup (sync + uninstall)
schema.integration-test.ts # Integration test against a live server
.github/workflows/
ci.yml # Lint, typecheck, unit + integration tests
cd.yml # Deploy + install on push to main
public/
logo.svg # Static assets
vitest.config.ts # Integration test runner config
vitest.unit.config.ts # Unit test runner config
tsconfig.json, tsconfig.spec.json
.nvmrc, .yarnrc.yml, .oxlintrc.json
README.md, LLMS.md
README.md, AGENTS.md, CLAUDE.md
```
## Key files
@@ -32,8 +43,10 @@ my-twenty-app/
| `src/application-config.ts` | **Required.** The main configuration file for your app. |
| `src/default-role.ts` | Default role controlling what your logic functions can access. |
| `src/constants/universal-identifiers.ts` | Auto-generated UUIDs and metadata (display name, description). |
| `src/__tests__/` | Integration tests (setup + example test). |
| `src/front-components/`, `src/navigation-menu-items/`, `src/page-layouts/` | A starter welcome page: a front component rendered by a standalone page layout, reachable from the sidebar. |
| `src/__tests__/` | A unit test plus an integration test (with its global setup) that syncs the app against a real server. |
| `public/` | Static assets (images, fonts) served with your app. |
| `AGENTS.md` / `CLAUDE.md` | Guidance for AI coding agents working on the app. |
<Note>
**File organization is up to you.** The folders above are conventions — the SDK detects entities via AST analysis on `export default defineEntity(...)` calls regardless of where the file lives.
@@ -47,15 +60,18 @@ Both Twenty SDK packages belong under `devDependencies`, not `dependencies`:
{
"dependencies": {},
"devDependencies": {
"twenty-client-sdk": "^2.13.0",
"twenty-sdk": "^2.13.0"
"twenty-client-sdk": "2.20.0",
"twenty-sdk": "2.20.0",
"twenty-ui": "1.0.0-alpha.1"
}
}
```
The scaffolder pins `twenty-sdk` and `twenty-client-sdk` to its own version — keep the two in sync when upgrading.
- **`twenty-sdk`** ships the `twenty` CLI and the build/scaffolding tooling. It only runs at development and build time and is never imported by your published app's runtime.
- **`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 build` emits a warning when either is still listed under `dependencies`.
Keeping either package under `dependencies` pulls it into the installed app's runtime bundle, where it is dead weight. `twenty dev: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.
@@ -5,10 +5,10 @@ icon: "wrench"
---
- **Docker errors** — Make sure Docker Desktop (or the daemon) is running before `yarn twenty docker:start`. The error message will show the right start command for your OS.
- **Wrong Node version** — Need 24+. Check with `node -v`.
- **Wrong Node version** — Need 24.5+ (`engines.node: ^24.5.0`). Check with `node -v`.
- **Yarn 4 missing** — Run `corepack enable`.
- **Dependencies broken** — `rm -rf node_modules && yarn install`.
- **`twenty-sdk` errors after upgrading to v2.8.0** — It moved from `dependencies` to `devDependencies` in v2.8.0. See [Project Structure → Dependencies](/developers/extend/apps/getting-started/project-structure#dependencies).
- **`twenty build` warns about `twenty-client-sdk` under `dependencies`** — It is provided at runtime by Twenty, so it should be moved to `devDependencies` alongside `twenty-sdk`. See [Project Structure → Dependencies](/developers/extend/apps/getting-started/project-structure#dependencies).
- **`twenty dev:build` warns about `twenty-client-sdk` under `dependencies`** — It is provided at runtime by Twenty, so it should be moved to `devDependencies` alongside `twenty-sdk`. See [Project Structure → Dependencies](/developers/extend/apps/getting-started/project-structure#dependencies).
Stuck? Ask on the [Twenty Discord](https://discord.com/channels/1130383047699738754/1130386664812982322).