A minimal Clone of Google Keep written in ReactJS with Material UI Components, themed to look exactly like Google Keep, with complex features like sharing, archiving, reminders etc. shoved away. The backend is a GraphQL server written in Golang, with data persisted in SQLite DB file, via GORM. The server implementation is complete with Cookie based Authentication, implemented using Authboss.
List - Displays notes as one item per row
Tile - Displays notes as tiles, and spread across the canvas
ReactJS - See Web source
Complete frontend JS framework
Follows React Hooks pattern
MaterialUI - See Login.js
Follows the new Material Design guidelines (known as Material v2)
Completely themed to adapt Google's version for Keep - See theme.js
Uses Montserrat font to match Google's Product Sans (See this Subreddit post) and Roboto font - See fonts.js
MaterialUI Icons - See AppBar.js
Reach Router - See App.js
Complete GraphQL client-side JS library
Provides React-hooks based implementations
Has Subscriptions (via Websockets) for dynamic updates from server (to create/delete notes with different tabs open)
Axios - React Hooks - See Login.js
Gorilla Mux - See main.go#main()
GORM - See models_gen.go
gqlgen - See resolver.go
Docker - Multistage build - See Dockerfile
Builds a deployable Docker image in 3 stages
Stage 1 - Builds runtime binary for Golang server
Stage 2 - Builds Production-ready ReactJS artifacts
Stage 3 - Assembles the artifacts from Stage 1 & Stage 2, and builds a container image
Heroku - Container Deployment - See heroku.yml
git push
This diagram explains the high-level architecture design of this project. This stack is a Monolith, with frontend-backend-database all packed into one single container deployment. Frontend is a ReactJS stack.
The Frontend is built with ReactJS using Material UI React components. The state management is through React's Hooks for State, Context & Reducer (see store.js
). The main application is available at root /
, which on load tries to load the noteitems.
Since the user will not authenticated by this time, the Router navigates the user to /login
where the user can enter email
& password
to login. To register for a new user, the user clicks on the 'Register' link to navigate to /register
route. The user may enter any name
, email
(no email verification in place) and password
. All Login & Registration HTTP calls are REST and are made via Axios React Hooks API.
Once logged in, a session cookie will be set in the browser. Now, the GraphQL API is available at /query
and URQL client loads all the Notes, Labels & User information, in a single query (However, has to be optimised, as URQL's caching mechanism, makes involuntary calls, whenever any of the mutation happens). UI displays the items. User may create, update, delete note items, and may also create & assign/unassign labels to note items. The labels may be added, but update/delete hasn't be implemented now. User can sign out, by clicking the 'Profile' icon and then 'Sign Out' button.
The Backend is built with Golang and no server framework is used, except Gorilla Mux, which provides utils for routing. The router consists for 3 major routes:
/
- handles UI resources
/query
- handles GraphQL requests and will be delegated to gqlgen generated GraphQL handlers. Throws NotAuthenticated
error, if user is unauthenticated. Also, understands user information, via session cookie.
/auth
- handles all authentication related requests and will be delegated to AuthBoss framework. The /auth/register
, /auth/login
& /auth/logout
routes handle Registration, Login & Logout respectively.
The DB is a SQLite DB and the persistence is a file
based API. GORM allows quick and easy Database modelling. The database tables are generated as per the modelling defined as Go Structs (see models_gen.go). The database modelling is done as per this ER Diagram
Both gqlgen & AuthBoss has resolvers. gqlgen's resolvers (see resolver.go
) helps in resolving Notes related data from database. While AuthBoss's resolvers (see storer.go
) help in resolving user related information.
The Deployment is through a muti-stage Docker build, which facilitates building Go binary and ReactJS artifacts in one single command. The Docker image generated is a Monolith, which can be deployed & run, without any other external setup.
git clone https://github.com/anselm94/googlekeepclone.git
cd googlekeepclone
docker build -t anselm94/googlekeepclone .
docker run -p 8080:8080 -e PORT=8080 anselm94/googlekeepclone:latest
git clone https://github.com/anselm94/googlekeepclone.git
cd googlekeepclone/web
/build
folderEXPORT REACT_APP_WEBSOCKET_ENDPOINT=ws://localhost:8080/query
npm install
npm run build
cd ..
export HOST=http://localhost
export PORT=3000
export STATIC_DIR=web/build
export DB_FILE=keepclone.db
export COOKIE_STORE_KEY=$(uuidgen | base64)
export SESSION_STORE_KEY=$(uuidgen | base64)
go run ./cmd/server/main.go
git clone https://github.com/anselm94/googlekeepclone.git
Download and Install Visual Studio Code
Start the Go server in Debug mode. See launch.json
Start the React Dev Server task. See tasks.json
Launches https://localhost:3000 in the browser
MIT License
Copyright (c) 2020 Merbin J Anselm
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.