# Twenty defines your CRM schema as code, and stops short of the data

> An open-source CRM positioned as the alternative to Salesforce, where objects, fields and views are defined in TypeScript and published to a workspace. The monorepo is Yarn-only on Node 24.5, carries about two dozen transitive pins, and its agent-skills install command points at a branch that does not exist until your first publish.

**twentyhq/twenty** — Open-source CRM positioned as an alternative to Salesforce, letting technical teams define objects, fields, and views as code on NestJS, PostgreSQL, and GraphQL.

- Repository: https://github.com/twentyhq/twenty
- Website: https://twenty.com
- Stars: 57,490 · Forks: 9,291
- Language: TypeScript
- License: not declared
- Published: 2026-08-04 · Updated: 2026-08-18 · Language: en
- Canonical page: https://hysenlabs.com/projects/twentyhq-twenty

## The skills install points at a branch that does not exist yet

The most telling limitation here is a sentence admitting a branch has not been created. The documented way to install the official Twenty app skills for a coding agent is one command pointing at the agent-skills branch of this repository, and the text then states that the branch is created by the first successful publish from main, and that until then you should follow the local build instructions. So on a fresh clone the headline install for agent harnesses does not resolve, and the documented workaround is to build the skills yourself before you can install them. That is a bootstrap ordering problem rather than a defect, but it has a real cost: anyone evaluating the agent tooling has to do a local build first, and the failure a newcomer meets is an unresolvable git reference rather than a message explaining the sequence.

```bash
npx skills add https://github.com/twentyhq/twenty/tree/agent-skills --list
```

A separate SKILLS.md file at the repository root is said to explain the other skill families and who each is for.

## The manifest refuses npm and pins Node 24.5

The root package manifest is unusually prescriptive about its toolchain, and it says so in the engines field. Node is a caret range on 24.5.0, Yarn is 4.0.2 or newer, and the npm entry is not a version at all but the literal string please-use-yarn. A packageManager field pins yarn at 4.13.0, and a .nvmrc sits at the top of the tree. The consequence is that this monorepo is Yarn-only by declaration rather than by preference, and an npm or pnpm install is turned away instead of quietly working. That matters most for CI and for new contributors, whose first instinct on a TypeScript repository is npm, and it constrains self-hosting as well: anyone building the images needs a Node 24.5 or newer runtime before the database and queue side of the stack even enters the picture.

## About two dozen transitive pins live in a single resolutions block

Look past the direct dependencies and the resolutions field is where the ongoing maintenance cost sits. It pins graphql to an exact patch, sharp to a newer point release than its caret range would otherwise permit, js-yaml and its dependencies to fixed versions, the OpenTelemetry API to an exact number, chokidar, tmp, a specific Angular devkit core version, yeoman-environment, express and its query parser, and a cluster of narrower pins under the module-federation and Zapier platform packages. There is also a yarn patch entry redirecting one front-matter version to a patch file stored inside the repository. The consequence is that every security bump in any of those packages is a change to this file plus a check that the patch still applies, and anyone installing a published app rather than cloning the monorepo inherits none of it. A file this dense is also where a supply-chain problem would sit unnoticed.

## Two release trains cut on the same day, sharing a minor number

The three most recent releases were all published on 2026-09-28, and they are not three versions of one thing. Two are SDK releases, v2.43.0 and v2.42.0, and one is the main application, v2.43.0, each under its own tag prefix. The SDK and the server are therefore versioned independently while sharing minor and patch numbers, so the bare string 2.43.0 is ambiguous and only becomes meaningful with the prefix in front of it. Having two SDK tags and an application tag cut on the same day points to a coordinated release, but the numbering does not record which SDK release belongs with which server release. For anyone pinning a self-hosted deployment this is the detail to get right, because an SDK built against one minor and run against another is the kind of mismatch that produces a confusing failure rather than a clean error at startup.

## The cloud path trades version control for always being current

Two installation routes are offered and they are opposites. The cloud route is a signup, and the description of the result is worth reading closely: a workspace in under a minute, with no infrastructure to manage and always up to date. The self-hosting route is Docker Compose, or a local setup from a guide, and it means running the stack yourself, which given the declared stack means TypeScript services on NestJS with BullMQ for queues, alongside PostgreSQL and Redis, behind a React front end. The phrase always up to date is the entire trade. You avoid maintenance and you give up version pinning, and your schema sits on infrastructure whose upgrade cadence you do not control. That is a reasonable default for a team wanting a CRM this week and a poor one for a team that needs to know what changed last Tuesday, which is also the team the rest of this repository is written for.

## The schema is code, and the migration story is the part left out

The pitch is that objects, fields and views are defined in code rather than assembled by clicking, and the example is short enough to read in full. An object declares a singular and a plural name, singular and plural labels, and a fields array where each field carries a name, a label and a type drawn from an enum, with text, currency and date-time used in the sample. You scaffold a new app with a create command, then ship it to your workspace with a publish command that takes a private flag, and the development guide is said to cover objects, views, agents and logic functions. What none of that covers is the path from a workspace that already holds data to one built this way. No import, export or migration step appears anywhere, so for a team replacing an existing CRM the schema-as-code benefit arrives only after the difficult part, and the difficult part is the one not addressed.

## GitHub cannot classify the licence, and the manifest says AGPL-3.0

Check the licence the way most people check it, on the repository page, and this project comes back unclassified: the platform's own licence detection did not identify one. The authoritative statement sits one level down, in the root package manifest, which declares AGPL-3.0, and a LICENSE file is present at the top of the tree. So the file to read is the manifest rather than the badge, and the discrepancy is worth knowing before anyone builds a compliance story on the repository page. The practical consequence for an adopting team is small but real, because an unclassified repository is the sort of thing a procurement check flags, and the answer it turns out to be, AGPL-3.0, carries its own obligations for software delivered as a network service.

## Conclusion

Adopt Twenty when your team wants its CRM schema under version control and is willing to run the stack, because objects, fields and views as code is a real difference from a click-together CRM and the manifest is honest about what the build demands. Do not adopt it expecting a path off your existing CRM: no import, export or migration step is described, so the hard part is unaddressed. Three things to settle first. The toolchain is Yarn-only on Node 24.5 or newer, with npm set to please-use-yarn. The agent-skills install cannot work until the first successful publish from main, so plan a local build. And read the licence from the package manifest rather than the repository badge, because the platform did not classify it while the manifest declares AGPL-3.0.

## FAQ

### How do I use Twenty as a CRM?

It is an open-source CRM you extend with code. You scaffold an app, define objects, fields and views as code, and publish it to your workspace. The building blocks it names are objects, views, workflows and agents, and a cloud option is offered for teams that do not want to run infrastructure at all.

### How do I install Twenty?

There are three routes: sign up for the cloud, scaffold an app with npx create-twenty-app, or self-host with Docker Compose. Note the toolchain requirement, since the manifest declares Node 24.5 or newer, Yarn 4.0.2 or newer, and sets the npm entry to please-use-yarn.

### Can I extend Twenty with a coding agent?

Yes, through the official app skills, which are said to work in Claude Code, Codex, Cursor, Pi and any other harness supported by the skills CLI. The install command points at an agent-skills branch created by the first successful publish from main, so until that publish happens you have to build the skills locally first.

### What licence does Twenty use?

The root package manifest declares AGPL-3.0 and a LICENSE file sits at the repository root, but the platform's own licence detection did not classify the project. Read the manifest rather than the repository page, since AGPL-3.0 carries obligations for software delivered as a network service.

## Sources

- [Official documentation](https://twenty.com)
- [Official README](https://github.com/twentyhq/twenty#readme)
- [Project repository](https://github.com/twentyhq/twenty)
- [Release notes](https://github.com/twentyhq/twenty/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/twentyhq-twenty
