Real-time notes is a rich text editor that supports collaborative editing built entirely in Typescript.
You can check out a live version of the app here: https://realtime-notes.surbina.dev/
Important: if the app has been inactive for some time, it may happen that when loading it again, it will timeout (probably due to some cold start in the server, though I still need to figure out what is precisely happening). If you stumble upon this issue, try reloading the app again.
This project was built using the following engines:
- NodeJS v16.15.1
- NPM 8.11.0
Be sure to use a compatible version when running it.
To set up the project for development, start by cloning the repository:
git clone https://github.com/surbina/realtime-notes.git
cd realtime-notes
Then, install the repo dependencies:
npm i
To run the app, you'll need to create a Firebase app. Then make a copy of the .env.template
file, and remove the .template
suffix from the name.
Then you'll need to get a Firebase Service Account and a Firebase Config. Once you have those, you should stringify them and store them in FIREBASE_SERVICE_ACCOUNT
and NEXT_PUBLIC_FIREBASE_CONFIG
env variables from your .env
file.
Finally, run the following command to populate the env variables:
source .env
After installing your project, you should be able to execute it by running the following command:
npm run dev
Below you can find a list of the core technologies used in this project and a short description of their purpose.
- NextJS: Javascript framework for building apps that supports SSR out of the box.
- Slate: Rich text editor with support for React.
- slate-yjs: provides a collaboration solution to be used with Slate.
- MaterialUI: Component library that follows Material design.
- Hocuspocus: NodeJS backend that implements collaborative features using CRDT data structures provided by Yjs.
- Firestore: Realtime NoSQL database.
- Playwright: Testing framework to run integration tests in multiple browsers.
- Fly.io: Service used to deploy the backend server.
- Vercel: Service used to deploy the frontend server.
The application is deployed automatically using Fly.io and Vercel. Each time we push to main, a Github action will clone the project, build a docker image with the backend code, push it to the Fly registry, and start the server. At the same time, when we push to the main branch, Vercel takes care of deploying the frontend app.
To run the integration tests, ensure the app is running, and the E2E_APP_URL
is populated. Then, from the project root run:
npm run test:e2e
There are some features I would have loved to implement, but I couldn't due to time restrictions:
- Add the delete note feature
- Reduce the number of WebSocket connections
- Adopt one styling solution and use it across the project (for consistency)
- Handle API errors in the frontend
- Run checks before deployments in the CI pipeline
- Run integration tests when pushing commits to main branch in the CI pipeline
We follow the monorepo pattern:
- apps contains executable and deployable packages:
- integration-tests contains the integration test suite implemented using Playwright
Each app's check
script runs the linting and type-checking. Run it in all apps from the root by running: npm run check --workspaces
.