I’ve created an OSS library that makes it easy to create real-time web apps
Tags: devops, react, programming
Published: 2021-09-08 13:22:14

# I have developed an OSS

I have developed a OSS library called [Realtimely](https://kitaharamugiro.github.io/Realtimely/) that makes it easy to introduce fun **real-time elements into React apps**.
Realtimely uses GraphQL and communicate with AWS Cloud by websocket. Programmers who use this library can implement a websocket-based real-time experience by simply using the **hooks function provided by Realtimely** without being aware of complicated technology.
For example, you can implement a feature of sharing the position of the mouse cursor like the gif below with about 10 lines of code.

![realtime-cursor.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234396/2a9d3a51-e6ea-9428-1dca-8eec057239ad.gif)

```tsx
import {useRealtimeCursor} from 'realtimely';

export default () => {
    const {onMouseMove, renderCursors} = useRealtimeCursor()
    return (
        <div onMouseMove = {onMouseMove}>
                {renderCursors()}
        </div>
    )
}
```

I made a [demo page](https://d2vfno2gco8009.cloudfront.net/), so please feel free to try it.

# From launch to release
Now, from here, I would like to write in chronological order how we actually planned and released it.
  

Number of developers : 1 person
Production days : 18 days
Costs : AWS Free Tier 
Time spent in a day : 1 hour on weekdays 3 hours on holidays

## 8/19 (0th day from the start) Plan

The decisions made on the first day are as follows.

* **Use Case**
    * → Image of when to use this library
* **Product image**
    * → Image of how programmers use this library
* **Architecture**
    * → What will be used to achieve this?
    * This time, I wanted to make it as low-code and scalable as possible (to make things easier).
* **Identify and schedule necessary tasks**
    * List what I have to do
    * Estimate how long it will take

This time, I considered the use case with a fairly product-out idea, but I think that it is ideal to actually do it by the following procedure.
① Think about issues that are in trouble in actual development
② Find out if someone has already realized it
③ If it has been realized, consider whether it is really convenient or if there is another product image that is easier to use.

Anyone can publish OSS, but even if you create and publish something that has already been realized or is not based on  troublesome, there is a risk that you will end up with a product that interferes with everyone's search.

## 8/20 (1st day from the start) Investigation
I searched for a library that could do what I wanted to do, read the documentation, and tried it out.
The library was a REST-based library for creating "high-performance real-time apps."
Since the purpose was high performance, it turned out that state management using cache etc is included in the function and it is too much, and that developers must develop the back-end from full scratch and it is not easy to use. 
So I corrected the product direction, such as sharpening my product image so that Realtimely could be used easily.

Also, although the direction is different, **there are many things that can be referred to because the realization is similar**. I also looked at the HTTP response and used it as a reference for what kind of data structure looks good for my product.

## 8/21 - 8/26 (6th day from the start) First iteration
We implemented the sprint goal of "sharing cursor movement in real time" in the first 7 days.

### Touch AWS AppSync
AppSync is a managed service for GraphQL servers. There is a function to automatically generate GraphQL schema and resolver by connecting with DynamoDB table.
This time, I'd like to **enjoy low code**, so I decided to use AppSync.

There are no-code and low-code systems, but they have their limit or service characteristic. AppSync is no exception to this example, and there was a need to **design while taking care of the features of AppSync**.

### Design
I wrote down the API required to implement "move the cursor in real time", and examined whether it could be realized. This area was a form of thinking about "what you want to achieve" and "what you can do with AppSync".

### DB Design
DynamoDB is a scalable NoSQL database with a key-value store. DynamoDB has HashKey and SortKey keys, and we design the DB so that these combinations are unique. RealtimeCursor has the following schema.

| HashKey | SortKey |
|------------------|--------------------------------|
| URL#{URL} | UserId#{UserId} |

The {URL} and {UserId} will contain the actual values. The mouse cursor position (X,Y) and user information will be stored as Attributes for these keys. 

### Fast Implementation
The first and foremost thing I do in implementation is to focus on **speed**.
I don't care how dirty it is, as long as it does what I want it to do.
The reason for this is that I believe that the most efficient way to create a clean design is to write everything and then scrap and build.
I don't know what can be made common from the start.

### Refactoring
When I was able to achieve what I wanted with roughly dirty code, I refactored it.
If it's a web service, you may decide to release something that works without refactoring first.
In this case, we had to redesign it with careful consideration of the responsibilities and interface, because it had to be easy to use as an OSS library.

## 8/27-8/30 (Day 11 from start) Second iteration
This is the second iteration of the sprint goal: "Implement visualization of user actions" (e.g., when a user presses a button, other people can see it, or when a user enters text, it can be seen on other people's screens).

The development went smoothly because the code base was refactored and I knew roughly what I could do with AppSync.

## 8/31 (12th day after the start) Create a demo page
I deployed the Next.js project that I used for development by using Serverless Framework. I could deploy it to AWS in 5 minutes.
[Demo page](https://d2vfno2gco8009.cloudfront.net/)

## 9/1-9/4 (Day 16 of development) Creating documentation
I used a documents framework called docusaurus to create the documentation. docusaurus is maintained by facebook and is very well done product.

First, I listed what I was going to write in a big list, and then I started to write.

### Think about what I'm going to write.
- [x]  Introduction
- [x]  Getting Started
    - [x]  Installation
    - [x]  Demo
    - [x]  Realtime Cursor
    - [x]  Realtime User Presence
    - [x]  Realtime User Action
- [x]  API Guides
    - [x]  useXXX
- [x]  How it works
    - [x]  Architecture
    - [x] Self hosted Backend
- [x]  RoadMap

### Write documents
This is the hardest part. This was the hardest part.

### Making it in English
Since docusaurus has the i18n feature, I made the document in English(Original is Japanese).
Basically, I just let google translate translate it and reviewed it briefly.

### Deploy to Github Pages
This was also a feature in docusaurus, so it was easy to do.

### Other tasks
#### Create a logo.
I used a logo generator.

#### Create a donation window.
I also created a donation window using [ko-fi](https://ko-fi.com/realtimely).
It connects to Stripe and allows you to **donate by credit card**.

## 9/5-6 (18 days after development) npm public
It's time to publish. For details on how to publish to npm, please refer to [another article](https://blog.logrocket.com/the-complete-guide-to-publishing-a-react-package-to-npm/). This time, I'll write roughly.

### Create an npm account
Create an account at https://www.npmjs.com/.

### Compile TypeScript into a .js file.
Write tsconfig.json and then

```
tsc -d
```

### yarn publish
You will be asked to login to npm, just enter your email and password.

### publish
I could publish really easily.
[After publishing](https://www.npmjs.com/package/realtimely)

I've used the npm library for so long that I felt guilty about stepping into the ring with my dirty feet.

### Debugging
I installed realtimely in a different repository and tried to use it, but it gave me an error and wouldn't work...
I used a day for debugging.

* Library dependencies
* Error in loading CSS
* Dependent library error

## The future
Since I prioritized the speed of release, the library is not production-ready at this point. I hope that you will use it only at the PoC level to see what it is like to add real-time elements to your application.

From now on, I'll be working on solving issues to make it production-ready and developing more user-friendly features. Please watch over us with warm eyes.

[Document](https://kitaharamugiro.github.io/Realtimely/)
[Demo](https://d2vfno2gco8009.cloudfront.net/)