This document describes the high-level architecture of Cella.
Cella in general is targeted towards being a template for SaaS development. But that is a large segment. So when to use / not use cella? Here are some thoughts on that. Use cella if the below matches your product/development requirements:
- frequent-use or heavy use web applications
- focused on user generated content that requires some form of authentication/authorization. So either semi-public or private access.
- Requires a great UX on different device, but native apps are not a direct priority
- Development budget and time is limited
- Fullstack development is seens as beneficial to work effectively and to provide engineering stability.
- Type safe, without overdoing it.
- Only build what you are going to use yourself.
- Stay humble and remain a template, not a framework. So prevent abstraction layers and leverage libraries to the fullest extent.
- A single/narrow stack: ie. Cella uses Drizzle ORM and will not make it replaceable with another ORM.
- Modularity. As CellaJS will grow, we need to make sure you can scaffold only the modules that you need.
- Open standards. Our long term vision is that each Cella - as in each cell - can speak fluently with other cells.
- Focused on client-side rendering (CSR) and - once it becomes relevant - static site generation (SSG). This seems to align best with our hybrid idiom to support offline and sync capabilities and reduce 'server dependency'.
.
├── backend
| ├── .db Location of db when using pglite
| ├── emails Email templates with jsx-email
│ ├── drizzle DB migrations
│ ├── seed Seed scripts
│ ├── src
│ │ ├── db Connect, table schemas
│ │ ├── lib 3rd part libs & important helpers
│ │ ├── middlewares Hono middlewares
│ │ ├── modules Modular distribution of routes, schemas etc
│ │ ├── permissions Setup of your authorization layer
│ │ └── utils Generic functions
├── config Shared config: default, development, production
├── frontend Frontend SPA
│ ├── public
│ ├── src
│ │ ├── hooks Generic react hooks
│ │ ├── json Static JSON
│ │ ├── lib Library code and core helper functions
│ │ ├── modules Modular distribution of components
│ │ ├── routes Code-based routes
│ │ ├── store Zustand data stores
│ │ ├── utils Generic functions
├── info General info
├── locales Translations
└── tus TUS server
Entities can be split in four types:
- All entities (
user
,organization
,attachments
) PageEntity
: Entity that can be searched for (user
,organization
)ContextEntity
: Has memberships (organization
)ProductEntity
: Content related entities without membership (attachment
)
The default cella setup has one example product entity - attachments
- and one context: organizations
.
An OpenAPI is built with zod-openapi. Please read the readme in this middleware before you get started.
Both frontend and backend already have many modules in common, such as authentication
, users
and organizations
. There are more frontend modules however, also for home
, marketing
, navigation
. The benefit of modularity is twofold: better code (readability, portability etc) and to make receiving cella updates possible.
Zooming in on some of the frontend modules:
common
: a cella-predefined set of reusable react components and servicesui
: Full with shadcn UI components. They have some small tweaks however and it is to be expected you will customize them yourself further.attachments
: product entity module that has support for offline, optimistic updates and realtime sync.
Link to valuable resources: