Recently, I created a project management tool called enamel. It’s now used by my employer, and hopefully I can sell it to more customers.

In this tutorial series, we are going to build this app from scratch:

Teaching how to build my own product sounds a bit weird. By the end of the tutorial, you will know how to build my product and so you can become my competitor. But building a business is much more than a product. So I’m not worried about that at all. You can use the code however you want.

The reason I’m doing this is that I learned so much and had fun along the way and I want to share with you my experience.

What Exactly Are We Building?

What we are building is essentially a simplified version of Wrike. It’s also similar to asana. Wrike has lots of features, but we are only building the following:

folders and sub folders

tasks and subtasks

User authentication

groups

set status, set due date, and assign a member to a task

share folders to a team, groups or members

keep a time log

That’s still a lot!

Here is a few screenshots of the app.

Workspace is the main view of the app. On the left, you see a team, folders and subfolders. In the middle is a list of tasks in the selected folder. And on the right is a task detail.

Workspace

This is the accounts page where you manage users and groups. A user has a role: administrator, regular user, collaborator, or external user. Wrike also has these roles, but for our app, it’s simpler. I will explain the difference among each role in a later post. We can also create a group.

Accounts page

Tech Stack

Here is the tech stack we are going to use.

Frontend — Vue.js, Vuex, Vue Router, Apollo

Backend — node.js, Express, Apollo, graphql-yoga

DB — MongoDB

It’s a typical fullstack JS stack, except Apollo. Apollo is a library on top of GraphQL. I use Apollo for both client and server, but they are independent. You can use only client or server if you want.

Requirements

This is an advanced tutorial. There are so many things to build, so I’m not going to explain each technology in detail.

You should know Vue.js and MongoDB. Backend is just a simple API server, so as long as you know javascript and ES6, I think you will be fine. Basic understanding of GraphQL is helpful, but I will try to explain Apollo as much as I can since it’s less known and the information is not easy to find.

I have not decided whether or not to explain CSS. Usually a tutorial on web development either uses CSS framework or skip the explanation completely, which is reasonable. But when I was building this app, actually what I struggled the most is CSS. There are so many things I didn’t know and I spent a lot of time googling. I will try to explain the tricky part, but otherwise just copy paste the CSS and you are good to go.

Let’s Build Backend

Enough talk. Let’s write some code! We are going to to create backend first.

The complete code is available on github.

Create a root directory enamel and create a server folder inside it.

mkdir enamel && cd enamel

git init

mkdir server && cd server

Inside server , create package.json with the following code:

// server/package.json

{

"name": "enamel_server",

"version": "1.0.0",

"description": "",

"main": "app.js",

"scripts": {

"start": "node src/app.js",

"dev": "./node_modules/nodemon/bin/nodemon.js src/app.js"

},

"author": "",

"license": "ISC",

"dependencies": {

"bcrypt": "^2.0.1",

"dotenv": "^6.0.0",

"graphql": "^0.13.2",

"graphql-yoga": "1.14.10",

"jsonwebtoken": "^8.3.0",

"moment": "^2.22.2",

"mongoose": "^5.1.5",

"nodemailer": "^4.6.7",

"nodemon": "^1.17.5"

}

}

These are all the dependencies for the backend. Not a lot, don’t you think? I mean, where is Express? Well, you don’t see Express here because graphql-yoga includes it. graphql-yoga is sort of a framework for GraphQL server which is built on top Apollo.

Go ahead and install the dependencies.

yarn

Or id you prefer npm,

npm i

Before I forget, add .gitignore

// server/.gitignore

.DS_Store

node_modules/

npm-debug.log*

yarn-debug.log*

yarn-error.log* .env

If you haven’t already, download MongoDB and run the process.

mongod

Create .env inside server and put the mongoDB URI:

MONGODB_URI=mongodb://localhost:27017/enamel

Create src inside server

mkdir src

Now the directory looks like this:

Application Code

Inside server/src , create app.js and paste this code. This file won’t change in the future.

// server/src/app.js

const { GraphQLServer } = require('graphql-yoga')

const mongoose = require('mongoose')

require('dotenv').config()

const resolvers = require('./resolvers') mongoose.connect(process.env.MONGODB_URI, { useNewUrlParser: true })

const db = mongoose.connection

db.on("error", console.error.bind(console, "connection error"))

db.once("open", function(callback){

console.log("Connection Succeeded")

}) const server = new GraphQLServer({

typeDefs: 'src/schema.graphql',

resolvers,

context: req => req,

}) const options = {

port: process.env.PORT || 5500,

endpoint: '/graphql',

subscriptions: '/subscriptions',

playground: '/playground',

} server.start(options, ({ port }) => console.log(`Server is running on port ${port}`))

To create a GraphQLServer, you need typeDefs and resolvers. I like to keep typeDefs in a separate file, so let’s create schema.graphql and put this dummy code:

// server/src/schema.graphql

type Query {

test: String

}

and resolvers.js

// server/src/resolvers.js

const resolvers = {

Query: {

test (_, args, context) {

return 'Hello World!'

}

}

} module.exports = resolvers

Now we have the basic code set, let’s run the server:

yarn dev

Go to localhost:5500/playground and you will see a beautiful GraphQL playground. Let’s run the query we just defined. Type the query on the left and

We use nodemon to automatically restart on file change. However, by default, it does not watch file changes on non-js files like schema.graphql . To fix that, add the following at the end of package.json

"nodemonConfig": {

"ext": "js,json,graphql"

}

That’s it for part 1! Check the github for reference if you need it.

In part 2, we are going to continue building backend.

I’m not sure how many blogs posts it takes to complete this tutorial or how soon the tutorial will be available, but if you liked this post, please give it some claps! It motivates me to write more.

I will see you in the next post!