CAIN Stack template to quickly build nativ cross platform applications with web technologies.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
max 55a29cc4ca „docker-compose.yaml“ ändern 5 months ago
.vscode add .env support 8 months ago
client missing dependencie 5 months ago
server clean up code a bit 6 months ago
.gitignore mashallah fix bugs 6 months ago update readme 6 months ago
docker-compose.yaml „docker-compose.yaml“ ändern 5 months ago

CAIN Stack template V2

Please read the following doc carefully to avoid any difficulties and misunderstandings.


This project is a template to build an offline first web application with authentication, that can be ported easily to other platforms (Android, iOS, Electron). It runs on the CAIN Stack which consists of following technologies:


  • Complete User authentication with confirm mail, password forget, user roles and more
  • Admin Panel for editing users
  • Private and shared database (admins can edit every document in every database)
  • Fully functional offline and syncing enabled by default
  • Native Apis like calling network state, camera and filesystem (more can be easily added with capacitor )
  • Cross Platform
  • Chat function (beta)


  • New Interface + designated desktop ui
  • Private Chats, which can even be initiated offline
  • Img-Upload Component with native Filepicker / Gallery, Camera and Cropper
  • User profiles with images and bio
  • Enhanced Api Security
  • Search Function v0. 1
  • Skeleton preloading and refresher
  • Lazyloading Images
  • Decreased Client Bundle Size by 18%


Frontend framework: Angular, PouchDB as local database, Ionic for cross platform components and capacitor as native api wrapper.


Requirements: Installed Ionic Cli and NodeJS. Install the client dependencies by cd client and running npm i . Start the client framework by running ionic serve .


Located at client/src/app/core .

Data Service

The heart of the Cain Stack. The initDatabase function gets initiated when the user logs in. It filters the names and remote addresses of the databases the user has access to and builds an object of PouchDB instances. Afterwards it starts the initRemoteSync , which starts the synchronisation of the local with the remote databases. The data service includes many document, attachment and database functions, to be used in your own services (see client/src/app/services ). Visit [pouchdb. com]( html) for the full api list.

Auth Service

Querys the superlogin apis and handles the destruction of local databses when logging out. It also checks the locally saved user token and therefore enables offline reauthentication.

User Service

Handles all User Doc related functions, like saving the user data locally, editing profile details and getting profile images.

Chat Service

Handles all chat related functions. Mainly the creation of private Chats, the querying of all user chats and the chat messages of one particular conversation. To avoid any conflicts when creating a new private chat database, the createPrivateChatId function builds a unique conversation Id based on the usernames of the participants. Therefore it is possible to create a chat even when the user is offline.


Located at client/src/app/shared . Consists of components, helpers, modals and services. These can be used in your own pages. A quick overview of what is included:


  • Doc-List (Has an input doc object array and is used by the pages Feed, User-Profile, Me and Notes)
  • Error-Messages (used in the auth gateway client/src/app/auth-gateway )
  • Image-Upload (+cropper; can be used in any form and automatically chooses the correct filepicker and camera)
  • Info-Slider (displays information about the application; used in the page info )
  • Skeleton-Card (preloading screen to decrease perceived loading time and is used by the pages Feed, User-Profile, Me and Notes)


  • Email-Validator (checks if the email is already registered)
  • Search-Filter (querys the supplied doc for a keyword, used by the doc-list component)
  • Username-Validator (checks if the username is already registered)


  • Edit-Doc (used by the doc-list component)
  • Edit-Profile (used in the settings page to edit the user profile)
  • Edit-User (admin settings to modify a user; used in the settings page)


  • Image Service (used by the image-upload component)



Includes all pages regarding user authentication, registration and password resets.


Handles routing for the tab bar. Namingly the pages Feed, Me and Conversation List. Depending on the client device, it shows the tabbar on the bottom (mobile) or on the top (desktop).


Shows all documents of the shared database, by querying the shared-doc service ( client/src/app/services ).


Consists of two pages: Me and User-profile. Me shows the current user doc, User-Profile, the profile of any other user.


Consists of two pages: Chat and Conversations. Chat displays the messages of a single conversation, Conversations displays all chats the user is participating in.


Shows all documents of the private database, by querying the private-doc service ( client/src/app/services ).


Handles functions like *change profile, email, password, etc. *. For admin users shows an additional tab for managing users.


Android & iOS

Change your app name and id in the capacitor.config.json and ionic.config.json located in the root folder of client . For bulding please refer to the official capacitor documentation.


Use the pwa-asset-generator and the web-app-manifest-generator to theme your app, and change your app name in the index.html and manifest.webmanifest .

Client Misc

Image Lazyloading

Images are mostly lazyloaded with the help of ng-lazyload-image. If you create a new page, you have to import the LazyLoadImageModule in your page module. For a nice UI, images will fade in when they are lazyloaded. Have a look at the lazyload section in client/src/global.css . If you do not want to use lazyload for an <img> tag, you have to declare your own class and set opacity: 1 !important in your global. css.



Requirements: Installed NodeJS, NestJS and Docker / Docker-Compose locally. Run docker-compose up in the root folder. Open Fauxton, the couchdb gui and disable the cors policy in settings and after you edited the credentials in the docker-compose.yaml and .env file.

Important: When developing always open Fauxton in a private window, as its authentication document conflicts with the user document of the CAIN Stack application.


Put a .env file into the root of the server folder



DB Setup & Design Docs

The setup function ( server/src/core/db-setup.ts )is triggerd on server startup and automatically creates all necessary databases and design documents (can be found in server/core/design-docs ). For developing it can be useful to purge all databases. Just uncomment the function at the beginning of the setup handler, save, comment again and save again.

superlogin-config server/src/core/superlogin-config.ts

Authentication heavily relies on superlogin. Press the link to read the full documentation. Almost all main apis are included in this template.

Mailer settings

A confirmation e-mail can be sent when a user signs up or forgot his password. You can use a standard gmail account to send out those mails. Just enter your credentials into the MAILER_USR and MAILER_PW sections of the .env file. You then have to enable access throught less secure apps. You can also use SendMail or any other custom Nodemailer transport. Have a look in the mailer section of the superlogin-config.ts . If you want to enable the confirmation mails you can change the mailer configuration in the superlogin config file server/src/core/superlogin-config.ts under the local section. Mailer Templates can be modified in server/src/assets/email-templates .

sendConfirmEmail: false,
requireEmailConfirm: false,

User roles

User roles can be defined and will be automatically added to the user doc (see server/src/core/signup-handler.ts on line 30). By default users with the admin role will have access to all documents. Routes can be guarded by user role (see server/src/user/user.module.ts on line 23)

Server Core Services server/src/core/services

Auth service checks if the token of the bearer token corresponds with the token in the user document in couchdb. The stream service converts a buffer into an readable stream for optimized file responses.


User-Api server/src/user

The user controller is responsible for getting and edditing profile details and additional settings for admin users. The apis are protected by the superlogin middleware, see user.module.ts .

Chat-Api server/src/chat

After starting the server, the chat controller starts listening to changes in the chat-index database and creates the corresponding chat databases and adds the participants to the security document of these databases.

Help & support

Visit heichling. xyz and send me a message if you have any questions. Also check out maxperience. blog for more information.