## What & why The left-sidebar **Favorites** section was hidden whenever the user had no favorites, so it was effectively undiscoverable — and personal favorites could only be created via the record-level "Add to favorites" action or drag-drop. This PR: - **Always shows the Favorites section**, with an empty-state **"Add a favorite"** call-to-action. - Adds a **"+" on the Favorites header that opens the same "New menu item" side panel** the Workspace section already uses, so users can add personal **Objects, Views, Records, Links and Folders** directly from the sidebar. ## How Favorites and workspace navigation are the same `NavigationMenuItem` entity (a personal favorite simply has `userWorkspaceId` set). Rather than build a separate favorites-only flow, the shared add/edit side-panel subsystem is made **section-aware** (`NavigationMenuItemSection = 'workspace' | 'favorite'`): - a new `navigationMenuItemEditSectionState` atom records which section the panel is operating on; - a new `useNavigationMenuItemEditController` forks persistence — the **workspace** section stages changes in the draft (saved on layout-customization exit), while the **favorite** section creates/updates/deletes personal items **immediately** with `userWorkspaceId = current member`. This mirrors the existing `useHandleNavigationMenuItemDragAndDrop` fork. The existing add/edit hooks, pickers and title editors were rerouted through the controller and a section-aware items hook, so they work for both sections with no behavior change to the workspace flow. **Backend: no changes** — `canUserCreateNavigationMenuItem` already authorizes personal navigation menu items of every type for any authenticated user. ## Decisions & tradeoffs - **Folder button → unified "+":** the folder-only header button is replaced by the single "+" (Folder is one of the panel's options), matching the Workspace section. This removed the inline folder-create code path. - **Click-to-add only in v1:** dragging items from the panel directly into Favorites is deferred — those drag handles are disabled in the favorite section (the drag path is hardwired to workspace layout mode), with a defense-in-depth no-op in the drop handler. - **Persist-on-commit:** favorite title/URL edits hit the network once on blur/enter, never per keystroke. - **Personal color edits** change only the favorite's own color, never the shared object metadata (that remains a workspace-customization behavior). - The change touches ~37 files because it generalizes the shared subsystem rather than duplicating it; net diff is slightly negative (+605 / −636). ## Testing - `npx nx typecheck twenty-front` — passes - `npx nx lint twenty-front` (oxlint + oxfmt) — passes - `navigation-menu-item` unit tests — pass (incl. an updated `computeInsertIndexAndPosition` test covering personal items) - Manual end-to-end walkthrough still recommended before merge.
The #1 Open-Source CRM
Website ·
Documentation ·
Roadmap ·
Discord ·
Figma
Why Twenty
Twenty gives technical teams the building blocks for a custom CRM that meets complex business needs and quickly adapts as the business evolves. Twenty is the CRM you build, ship, and version like the rest of your stack.
Learn more about why we built Twenty
Installation
Cloud
The fastest way to get started. Sign up at twenty.com and spin up a workspace in under a minute, with no infrastructure to manage and always up to date.
Build an app
Scaffold a new app with the Twenty CLI:
npx create-twenty-app my-app
Define objects, fields, and views as code:
import { defineObject, FieldType } from 'twenty-sdk/define';
export default defineObject({
nameSingular: 'deal',
namePlural: 'deals',
labelSingular: 'Deal',
labelPlural: 'Deals',
fields: [
{ name: 'name', label: 'Name', type: FieldType.TEXT },
{ name: 'amount', label: 'Amount', type: FieldType.CURRENCY },
{ name: 'closeDate', label: 'Close Date', type: FieldType.DATE_TIME },
],
});
Then ship it to your workspace:
npx twenty app:publish --private
See the app development guide for objects, views, agents, and logic functions.
Self-hosting
Run Twenty on your own infrastructure with Docker Compose, or contribute locally via the local setup guide.
Everything you need
Twenty gives you the building blocks of a modern CRM (objects, views, workflows, and agents) and lets you extend them as code. Here's a tour of what's in the box.
Want to go deeper? Read the User Guide for product walkthroughs, or the
Documentation for developer reference.
|
|
|
|
|
|
Stack
TypeScript
Nx
NestJS, with BullMQ,
PostgreSQL,
Redis
React, with Jotai, Linaria and Lingui
Thanks
Thanks to these amazing services that we use and recommend for UI testing (Chromatic), code review (Greptile), catching bugs (Sentry) and translating (Crowdin).
Join the Community
Star the repo ·
Discord ·
Feature requests ·
Releases ·
X ·
LinkedIn ·
Crowdin ·
Contribute





