πŸ‘‹ Hello everyone, after a year of independent development, today I open source my Next. Js app-Chirpy, a privacy-protecting, theme-customizing commentary component SaaS.

Too long to see the version πŸ™ˆ

This is the GitHub Repo. Please light up 🌟 and contribute. For beginning and intermediate engineers, this is a great place to learn everything you need to know about how a complete SaaS works.

The official website is currently in beta testing, welcome to try. Chirp also supports Docker deployment if you want complete control of your data.

Preview πŸ‘€

Comment widget with rich text editing and Markdown Shortcuts (Markdown Live Preview, Similar to Typora writing experience)

Theme customization 🌈 (more customization items in development)

Component Usage Analysis Panel (Analytics) πŸ“ˆ

Beginner’s mind ❀ ️

When I was building my own blog, I wanted a feature-rich, quick-access comment component similar to Disqus, which has been criticized for selling users’ privacy and advertising without their consent for years. Here are some of the stories I retrieved:

Bloomberg LawDisqus Faces $3 Million Sanction Over Alleged GDPR Breachesfor multiple breaches of EU privacy law.

Disqus facing $3M fine in Norway for tracking users without consent

I have also used free comment systems based on GitHub API such as Gitalk Utterances. One of their obvious problems is that they only support GitHub login and are limited by GitHub’s own API, so many functions are not easy to do. Such as component usage analysis/Analytics.

Market components are basically lack of theme customization ability, in their own blogs, websites have a high probability of design disharmony caused by the sense of violation, so theme customization is also necessary.

Based on the above problems, I plan to make a completely open source comment component system that can also solve the above pain points.

Technology selection and evolution πŸ•Ί

Back in 2020, the React SSR framework Next. Js launched SSG (Static Site Generation) and ISR (Incremental Static Regeneration), which quickly became popular. Compared with the popularity of the static website generator Gatsby in 2019. (Remix is also a good option if you are rechoosing today. πŸ˜„)

Next, js πŸ†š Gatsby

Gatsby Next.js
SSR πŸ”΄ βœ…Β 
SSG βœ… βœ…Β 
ISR πŸ”΄ βœ…Β 
BUILD SPEED 🐌 ⚑ ️
HMR SPEED 🐌 ⚑ ️

NPM trend chart:

The ISR (Incremental static Update) feature of next.js is particularly suited for commenting component scenarios. Imagine thousands of IFrame comment components, with ISR rendering having both the flexibility of SSR and the accelerated support of CDN (less concurrent rendering). The following figure shows the ISR diagram:

At the beginning, Chirpy chose egoist’s Next FullStack Starter as the starting point. The main technology stack is: Next. Js + Prisma + GraphQL + TypeGraphQL + Tailwindcss. However, further development revealed that ORM Prisma does not support the Subscription/real-time API, which is an important feature for the user experience. After careful consideration, Backend was migrated to Hasura.

Prisma➑ ️Hasura

Prisma and Hasura are not strictly the same thing. Hasura is a GraphQL server that supports concurrent access to GraphQL databases such as PostgreSQL. It also provides a complete set of permissions. Prisma is an ORM. In order to support GraphQL, it still needs the corresponding resolver and corresponding permission control for handwriting, which costs a lot of development, but is correspondingly more flexible than Hasura.

Prisma Hasura
language TypeScript haskell
Type ORM GraphQL Server
GraphQL API 🟑 manually βœ… is generated by database Schema
High concurrency 🟑 is limited by node.js performance and application architecture βœ… (50M ram supports 1000 Q/SEC)
Subscription πŸ”΄ βœ…
flexibility βœ… 🟑

Architecture of Hasura applications

passportjs➑ ️next-auth

The user login system (third-party login + traditional account password) also has two mature choices. At the beginning, passportJS was selected, but in the in-depth development, many OAuth and security-related problems were encountered. Finally, it was reconstructed and changed to Next-Auth. Next-auth is more modern (it offers React Hooks, and the library itself is written in TypeScript), more secure, and easy to integrate with next.

passportjs next-auth
Third party login βœ… βœ…
Email password login βœ… βœ…Β 
Login without password βœ… βœ…Β 
security 🟑 βœ…
React Hooks πŸ”΄ βœ…
Next, js integration πŸ”΄ βœ…

Tailwindcss οΌ†Β twin.macro & radix-colors

Tailwind is an atomized CSS development framework that can significantly improve the efficiency of CSS development after you become familiar with it πŸš€; It also provides a complete and proven set of default theme configurations, as well as a rich library of SaaS UIs (not entirely free, but not too difficult to tailwind to write similar UIs, and more importantly, there are commonly used SaaS UI designs to reference. For me this design bitter hand is very helpful πŸ₯³).

In fact, Chirpy is used in conjunction with Twin. macro, which is a library that combines tailwind and CSS-in-JS (Styled component & Emotion), Early versions of Tailwind encountered situations in componentized development where style classes could not be overwritten because tailwind itself outputs atomic classes:

<p className="w-1 h-1">... </p>// Output CSS πŸ‘‡

.w-1	{
  width: 0.25rem;
}

.h-1	{
  height: 0.25rem;
}
Copy the code

Twin. macro version, no CSS required! Important overrides styles:

<p tw="w-1 h-1">.</p>// Output HTML & CSS πŸ‘‡<p class="random-name">.</p>. The random - name {width: 0.25 rem; Height: 0.25 rem; }Copy the code

Twin. macro also supports build-time verification, so invalid styles will be reported (like W-0.1) to avoid writing useless styles. Variants such as sm:(bG-Black hover:(BG-White W-10)). Of course, it’s not perfect. Tailwind can reuse existing CSS classes, and it generates new styles almost every TW, resulting in a larger bundle size Twin. It also does not support some of tailwind’s official plugins, such as: TailwindCSS-Typography (for editors). So the two are used together.

The Dark mode of tailwind mainly relies on Dark: variant (🌰 below). Almost every color value has to be written twice. My ideal Dark mode is automatic.

<div class="bg-white dark:bg-gray-900">.</div>
Copy the code

Therefore, two sets of light/dark colors are required here, and the radix-colors meet the requirements. But how would it work with Tailwind? The answer is CSS Variable.

First configure the tailwind theme:

module.exports = {
  theme: {
    colors: {
      bg: `var(--tw-colors-bg)`}},}Copy the code

Then inject styles into the application:

:root {
  --tw-colors-bg: white;
}
:root.dark {
  --tw-colors-bg: black;
}

Copy the code

Work with the next Themes to automatically switch the site CSS class when the user switches mode:

// Next -themes automatically switch mode when the user changes. Dark Whether<html class="dark">.</html>
Copy the code

This automatically refreshes the color when you apply a mode switch.

In addition to addressing the theme customization of components, Chirpy only needs to inject user-defined variable values at component rendering time.

Slate➑ ️tiptap

At the heart of the comments component experience is the rich text editor. Chirpy started with SLATE because it worked well with React, but there were some issues with markdown Shortcuts later in the development. Markdown Shortcuts didn’t work well, then moved to TipTap and improved functionality. The underlying layer is also based on the more stable ProseMirror.

slate tiptap
Based on the React ProseMirror
The stability of πŸ”΄Β issue βœ…Β 
Markdown shortcuts πŸ”΄ βœ…
Functional richness πŸ”΄ βœ…Β 

apollo-client➑ ️urql

Apollo-client is undoubtedly the most popular GraphQL client, and it was the original choice. I encountered 2 weird bugs shortly before I was ready to open source (some states don’t update). Search related questions also learned that Apollo regards open source as a marketing tool. In addition, I was always worried about its large bundle size, so I decided to migrate to urQL, a much smaller library. The reconfiguration proved to be worth it, reducing the bundle size by nearly 45KB.

apollo-client urql
bundle size 🟑 33 KB βœ… 7.1 KB
Next, js integration πŸ”΄ βœ… next – urql
Document Caching πŸ”΄ βœ…
Stale while Revalidate βœ…Β  βœ…Β 

Plausible πŸ“ˆ

At first Chirpy implemented a data statistics/Analytics, but later found that there were a lot of things to consider (aggregated data, performance, charts, etc.), which slowed down the development schedule. Marked beneath Each of the following choices, there are four choices marked beneath Each of the following choices: To better protect users’ privacy, Chirpy uses it to run on a separate server rather than directly using its service.

Chirpy overuses the front-end code marked beneath each of the following sentences to fit its own scenarios. At the same time, the script for sending data can be directly put into Chirpy’s bundle + remapping API interface for sending data, which can solve the problem of inaccurate data caused by browser advertising filter filtering out requests. So you can use Chirpy as a free and highly accurate Analytics tool πŸ˜‰.

CI & CD β™»

The CI/CD of the project relies heavily on GitHub actions. The development process is based on PR, and each PR check-in is preceded by Cypress(end-to-end testing), JEST (unit testing), and Next. Js bundle size changes (to avoid unintended bundle size problems).

Hasura Schema CI/CD will be introduced later to reduce schema upgrade problems.

Deploy πŸ’Ώ

There are four sections marked Next. Js, Hasura, and marked beneath:

  • Next. Js is naturally deployed to the company that developed it β†’ Vercel is the best choice, with better build performance, graphics and other optimizations than similar services like Netlify, and the deployment experience is superb.
  • Hasura has pre-installed a Caddy HTTP Server that can automatically sign HTTPS domain names and is also ready to support elastic load balancing in the future.
  • Each of the following instances are deployed separately to avoid affecting business data, and Caddy HTTP Server is added.
  • Hasura and Beneath each are deployed to a DigitalOcean VIRTUAL machine for their cost effectiveness and ease of use.

Cloudflare Images should be used to support image uploading in the future, which is fully functional and cost-effective.

Long term planning πŸ›Έ

The comment component is just my first step, and Chirpy will also consider making a chat component similar to Intercom (as shown below) after the function is gradually improved. Hasura + WebSocket architecture is naturally suitable for such a lightweight chat application. Chirpy aims to build a complete solution for open source user communication.

Community/community 🏘

As an open source project, I value community very much and encourage everyone to contribute (issue, discussion, PR). Once the plan has a certain amount of income, it will regularly give some money to the active developers and give back to the community.

Thank you so much for seeing this and welcome to Chirpy community at πŸ™Œ.