eb1ca1b9ec
## Summary
Logic-function bundles produced by the twenty-sdk CLI were ~1.18 MB even
for a one-line handler. Root cause: the SDK shipped as a single bundled
barrel (`twenty-sdk` → `dist/index.mjs`) that co-mingled server-side
definition factories with the front-component runtime, validation (zod),
and React. With no `\"sideEffects\"` declaration on the SDK package,
esbuild had to assume every module-level statement could have side
effects and refused to drop unused code.
This PR restructures the SDK so consumers' bundlers can tree-shake at
the leaf level:
- **Reorganized SDK source.** All server-side definition factories now
live under `src/sdk/define/` (agents, application, fields,
logic-functions, objects, page-layouts, roles, skills, views,
navigation-menu-items, etc.). All front-component runtime
(components, hooks, host APIs, command primitives) lives under
`src/sdk/front-component/`. The legacy bare `src/sdk/index.ts` is
removed; the bare `twenty-sdk` entry no longer exists.
- **Split the build configs by purpose / runtime env.** Replaced
`vite.config.sdk.ts` with two purpose-specific configs:
- `vite.config.define.ts` — node target, externals from package
`dependencies`, emits to `dist/define/**`
- `vite.config.front-component.ts` — browser/React target, emits to
`dist/front-component/**`
Both use `preserveModules: true` so each leaf ships as its own `.mjs`.
- **\`\"sideEffects\": false\`** on `twenty-sdk` so esbuild can drop
unreferenced re-exports.
- **\`package.json\` exports + \`typesVersions\`** updated: dropped the
bare \`.\` entry, added \`./front-component\`, and pointed \`./define\`
at the new per-module dist layout.
- **Migrated every internal/example/community app** to the new subpath
imports (`twenty-sdk/define`, `twenty-sdk/front-component`,
`twenty-sdk/ui`).
- **Added \`bundle-investigation\` internal app** that reproduces the
bundle bloat and demonstrates the fix.
- Cleaned up dead \`twenty-sdk/dist/sdk/...\` references in the
front-component story builder, the call-recording app, and the SDK
tsconfig.
## Bundle size impact
Measured with esbuild using the same options as the SDK CLI
(\`packages/twenty-apps/internal/bundle-investigation\`):
| Variant | Imports | Before | After |
| ----------------------- |
------------------------------------------------------- | ---------- |
--------- |
| \`01-bare\` | \`defineLogicFunction\` from \`twenty-sdk/define\` |
1177 KB | **1.6 KB** |
| \`02-with-sdk-client\` | + \`CoreApiClient\` from
\`twenty-client-sdk/core\` | 1177 KB | **1.9 KB** |
| \`03-fetch-issues\` | + GitHub GraphQL fetch + JWT signing + 2
mutations | 1181 KB | **5.8 KB** |
| \`05-via-define-subpath\` | same as \`01\`, via the public subpath |
1177 KB | **1.7 KB** |
That's a ~735× reduction on the bare baseline. Knock-on benefits for
Lambda warm + cold starts, S3 upload size, and \`/tmp\` disk usage in
warm containers.
## Test plan
- [x] \`npx nx run twenty-sdk:build\` succeeds
- [x] \`npx nx run twenty-sdk:typecheck\` passes
- [x] \`npx nx run twenty-sdk:test:unit\` passes (31 files / 257 tests)
- [x] \`npx nx run-many -t typecheck
--projects=twenty-front,twenty-server,twenty-front-component-renderer,twenty-sdk,twenty-shared,bundle-investigation\`
passes
- [x] \`node
packages/twenty-apps/internal/bundle-investigation/scripts/build-variants.mjs\`
produces the sizes above
- [ ] CI green
Made with [Cursor](https://cursor.com)
124 lines
3.1 KiB
JSON
124 lines
3.1 KiB
JSON
{
|
|
"name": "twenty-sdk",
|
|
"version": "1.22.0",
|
|
"sideEffects": false,
|
|
"bin": {
|
|
"twenty": "dist/cli.cjs"
|
|
},
|
|
"files": [
|
|
"dist",
|
|
"README.md",
|
|
"package.json"
|
|
],
|
|
"scripts": {
|
|
"build": "npx rimraf dist && npx vite build"
|
|
},
|
|
"keywords": [
|
|
"twenty",
|
|
"cli",
|
|
"sdk",
|
|
"crm",
|
|
"application",
|
|
"development"
|
|
],
|
|
"exports": {
|
|
"./define": {
|
|
"types": "./dist/define/index.d.ts",
|
|
"import": "./dist/define/index.mjs",
|
|
"require": "./dist/define/index.cjs"
|
|
},
|
|
"./front-component": {
|
|
"types": "./dist/front-component/index.d.ts",
|
|
"import": "./dist/front-component/index.mjs",
|
|
"require": "./dist/front-component/index.cjs"
|
|
},
|
|
"./ui": {
|
|
"types": "./dist/ui/index.d.ts",
|
|
"import": "./dist/ui/index.mjs",
|
|
"require": "./dist/ui/index.cjs"
|
|
},
|
|
"./cli": {
|
|
"types": "./dist/cli/operations/index.d.ts",
|
|
"import": "./dist/operations.mjs",
|
|
"require": "./dist/operations.cjs"
|
|
},
|
|
"./front-component-renderer": {
|
|
"types": "./dist/front-component-renderer/index.d.ts",
|
|
"import": "./dist/front-component-renderer.mjs",
|
|
"require": "./dist/front-component-renderer.cjs"
|
|
},
|
|
"./front-component-renderer/build": {
|
|
"types": "./dist/front-component-renderer/build/index.d.ts",
|
|
"import": "./dist/front-component-renderer/build.mjs",
|
|
"require": "./dist/front-component-renderer/build.cjs"
|
|
}
|
|
},
|
|
"license": "AGPL-3.0",
|
|
"dependencies": {
|
|
"@genql/cli": "^3.0.3",
|
|
"@genql/runtime": "^2.10.0",
|
|
"@sniptt/guards": "^0.2.0",
|
|
"axios": "^1.13.5",
|
|
"chalk": "^5.3.0",
|
|
"chokidar": "^4.0.0",
|
|
"commander": "^12.0.0",
|
|
"dotenv": "^16.4.0",
|
|
"esbuild": "^0.25.0",
|
|
"graphql": "^16.8.1",
|
|
"graphql-sse": "^2.5.4",
|
|
"ink": "^6.8.0",
|
|
"inquirer": "^10.0.0",
|
|
"jsonc-parser": "^3.2.0",
|
|
"preact": "^10.28.3",
|
|
"react": "^19.0.0",
|
|
"react-dom": "^19.0.0",
|
|
"tinyglobby": "^0.2.15",
|
|
"twenty-client-sdk": "workspace:*",
|
|
"typescript": "^5.9.2",
|
|
"uuid": "^13.0.0",
|
|
"vite": "^7.0.0",
|
|
"vite-tsconfig-paths": "^4.2.1",
|
|
"zod": "^4.1.11"
|
|
},
|
|
"devDependencies": {
|
|
"@prettier/sync": "^0.5.2",
|
|
"@types/inquirer": "^9.0.0",
|
|
"@types/node": "^24.0.0",
|
|
"@types/react": "^19.0.0",
|
|
"@types/react-dom": "^19.0.0",
|
|
"rollup-plugin-dts": "^6.4.1",
|
|
"ts-morph": "^25.0.0",
|
|
"tsx": "^4.7.0",
|
|
"twenty-shared": "workspace:*",
|
|
"twenty-ui": "workspace:*",
|
|
"vite-plugin-dts": "^4.5.4",
|
|
"wait-on": "^7.2.0"
|
|
},
|
|
"engines": {
|
|
"node": "^24.5.0",
|
|
"yarn": "^4.0.2"
|
|
},
|
|
"typesVersions": {
|
|
"*": {
|
|
"define": [
|
|
"dist/define/index.d.ts"
|
|
],
|
|
"front-component": [
|
|
"dist/front-component/index.d.ts"
|
|
],
|
|
"cli": [
|
|
"dist/cli/operations/index.d.ts"
|
|
],
|
|
"ui": [
|
|
"dist/ui/index.d.ts"
|
|
],
|
|
"front-component-renderer": [
|
|
"dist/front-component-renderer/index.d.ts"
|
|
],
|
|
"front-component-renderer/build": [
|
|
"dist/front-component-renderer/build/index.d.ts"
|
|
]
|
|
}
|
|
}
|
|
}
|