Api server for Tclone, a concise, fast, and feature rich Twitter clone built with MERN stack.

Overview

Api server for tclone

Try the app here

React frontend repo here

This project is my own take on building Twitter clone, I have tried to keep things simple and concise. With minimal modules needed, it is very lightweight and fast, yet very functional and feature-rich. Three parts of project viz, front-end, database and api server are separately hosted and this repo contains the api code which connects to the front-end app and database.

Things used

  • Express as an api server

  • MongoDB as database

  • Mongoose as Mongo JavaScript driver, model/schema validation

  • Passport/passport-local for authentication

  • Bcryptjs for hashed password storage and comparison

  • Cookies/express-session/connect-mongo for session management and storage

  • And a large part of my otherwise useless brain.

File structure (UPDATED!)

File structure is now more standard and consice, here is a rundown of project structure

  • models/
    • trend.model.js - contains mongoose schema's for models and their respective methods/statics
  • routes/
    • auth.js - contains authentication related routes, like /auth/login, /auth/logout, etc.
    • api.js - contains all other routes
  • controllers/
    • user.controller.js contains functions to be used in router, like getUser for /api/user/:username endpoint
    • ...
  • serializers/
    • post.serializer.js contains functions to serialize Post Object or Array and includes fields particular to authticated user.
    • ...
  • utils/
    • helpers.js containes some miscellaneous helper utilities like escapeHtml, etc
    • mddlewares.js middlewares like ensureLoggedIn
  • dummy-data/ contains json and script for parsing some pre-populated data
  • passport.js passport related congig and functions
  • app.js main express app.

This is the overview of what's contained in this repo.

Routes

Routes are divided into two parts /auth (routes/auth.js) and /api (routes/api.js). As it is inferred /auth contains authentication related sub routes, so user signup is done via POST /auth/signup endpoint and login is done via POST /auth/login. There is also GET /auth/login which returns 200 if user is logged in (has a session up) and is used by front-end code to check for logged-in session. Other routes fall under /api and these include GET /api/home_timeline to get post feed of authenticated user, POST /api/post to create a new post of user authenticated user, GET /api/search for posts related query by the user (not needed to be authenticated) and GET /api/trends to get trending hashtags,etc among others.

Database Models

There is bunch of mongoose models viz Auth, Post, Friendship, Trend, home_timeline, etc. All the functions which interacts with these models are contained in the same file as their schema (see models/). Any Api call or other models do not directly access the collection (represented by Models), instead they call their respective helper functions to get data, for example /api/home_timeline calls getTimeline in home_timline.js to get posts sorted and page wise. There is also some sandboxing to some models like Auth and Friendship, User model do not even store the Reference (_id) of Auth model or Friendship model, instead each Auth model containing user's hashed password, contains the user_id of user and not vice-versa. This accounts for additional security as User object is often populated into post object when sent to user, this method guaranties of no accidental leakage of password Hash or even its reference.

Pre_populating

Some data (tweets and users) is fed into database at server-start to get a bunch of posts in tclone app (data is updated not overwritten). These are actual recent tweets on Twitter and fetched via twitter api and then populated in database. Tweet Model on this project is exactly compatible with Tweet objects returned by Twitter api and this data is read from dummy_data/home_timeline.json, which is original return value of twitter api /statuses/home_timeline. This file can also be filled with any list of valid tweet objects (models/post.js) and that data will be appended to database, all of this behavior is controlled by dummy_data/pre_populate.js which is invoked upon successful connection to the mongo database.

Trend Analysis

Each post added to database is parsed for any #hastags or @user_mentions. These hashtags (along with storing in Post.entities) is stored in hashtags collection (Hashtag model) along with number of times it has been posted. From there Trending hashtags are retrieved as simply the ones with highest post volume . Selecting these highest volume hastags is done at a interval of (currently) 30 seconds, therefore trends are upadted realtime to what users are posting.

Search

Posts can be searched for text they contain; user mentions they contain (@prefix in query) and hashtags they contain (#prefix in query). Text search is done via MongoDB text search of indexes and for user mentions and hashtags, these are simply compared from post.entities.

Authentication

Authentication is done with passport local-strategy with sessions managed server side via cookies which are also httpOnly. Along with an api end point for checking logged in session (GET /auth/login) which returns success if user is logged in, subsequent api requests return 403 to flag inauthentication and is also used by front end to destroy session cookie.

Deploying

You will need some environment variables to run this, below is the how your environment variables should look like (.env file on local and heroku variables on heroku and something similar elsewhere)

MONGO_URL=<link to atlas address or wherever your mongoDB is deployed, defaults to 'mongodb://localhost/test'>
SESSION_SECRET=<passed to session middleware, defaults to 'my shitty session secret'>

# Push notifications keys. You can generate them with command "./node_modules/.bin/web-push generate-vapid-keys"
PUBLIC_VAPID_KEY=<public vapid key which also goes into React front-end>
PRIVATE_VAPID_KEY=<corresponding private key>
# This must be either a URL or a 'mailto:' address.
# For example: 'https://my-site.com/contact' or 'mailto: [email protected]'
WEB_PUSH_CONTACT="mailto: [email protected]"

After that just install deps and run npm run mon to start dev server via nodemon and npm run start to start server in production.

More

Are you serously still reading?

Comments
  • Bump express from 4.16.4 to 4.17.3

    Bump express from 4.16.4 to 4.17.3

    Bumps express from 4.16.4 to 4.17.3.

    Release notes

    Sourced from express's releases.

    4.17.3

    4.17.2

    4.17.1

    • Revert "Improve error message for null/undefined to res.status"

    4.17.0

    • Add express.raw to parse bodies into Buffer
    • Add express.text to parse bodies into string

    ... (truncated)

    Changelog

    Sourced from express's changelog.

    4.17.3 / 2022-02-16

    4.17.2 / 2021-12-16

    4.17.1 / 2019-05-25

    ... (truncated)

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 1
  • Bump minimist from 1.2.5 to 1.2.6

    Bump minimist from 1.2.5 to 1.2.6

    Bumps minimist from 1.2.5 to 1.2.6.

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 1
  • Bump socket.io from 2.3.0 to 2.4.0

    Bump socket.io from 2.3.0 to 2.4.0

    Bumps socket.io from 2.3.0 to 2.4.0.

    Release notes

    Sourced from socket.io's releases.

    2.4.0

    Related blog post: https://socket.io/blog/socket-io-2-4-0/

    Features (from Engine.IO)

    • add support for all cookie options (19cc582)
    • disable perMessageDeflate by default (5ad2736)

    Bug Fixes

    • security: do not allow all origins by default (f78a575)
    • properly overwrite the query sent in the handshake (d33a619)

    :warning: BREAKING CHANGE :warning:

    Previously, CORS was enabled by default, which meant that a Socket.IO server sent the necessary CORS headers (Access-Control-Allow-xxx) to any domain. This will not be the case anymore, and you now have to explicitly enable it.

    Please note that you are not impacted if:

    • you are using Socket.IO v2 and the origins option to restrict the list of allowed domains
    • you are using Socket.IO v3 (disabled by default)

    This commit also removes the support for '*' matchers and protocol-less URL:

    io.origins('https://example.com:443'); => io.origins(['https://example.com']);
    io.origins('localhost:3000');          => io.origins(['http://localhost:3000']);
    io.origins('http://localhost:*');      => io.origins(['http://localhost:3000']);
    io.origins('*:3000');                  => io.origins(['http://localhost:3000']);
    

    To restore the previous behavior (please use with caution):

    io.origins((_, callback) => {
      callback(null, true);
    });
    

    See also:

    Thanks a lot to @ni8walk3r for the security report.

    Links:

    ... (truncated)

    Changelog

    Sourced from socket.io's changelog.

    2.4.0 (2021-01-04)

    Bug Fixes

    • security: do not allow all origins by default (f78a575)
    • properly overwrite the query sent in the handshake (d33a619)
    Commits
    • 873fdc5 chore(release): 2.4.0
    • f78a575 fix(security): do not allow all origins by default
    • d33a619 fix: properly overwrite the query sent in the handshake
    • 3951a79 chore: bump engine.io version
    • 6fa026f ci: migrate to GitHub Actions
    • See full diff in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 1
  • Bump bl from 2.2.0 to 2.2.1

    Bump bl from 2.2.0 to 2.2.1

    Bumps bl from 2.2.0 to 2.2.1.

    Release notes

    Sourced from bl's releases.

    v2.2.1

    Fix unintialized memory access

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Bump qs and express

    Bump qs and express

    Bumps qs to 6.11.0 and updates ancestor dependency express. These dependencies need to be updated together.

    Updates qs from 6.5.2 to 6.11.0

    Changelog

    Sourced from qs's changelog.

    6.11.0

    • [New] [Fix] stringify: revert 0e903c0; add commaRoundTrip option (#442)
    • [readme] fix version badge

    6.10.5

    • [Fix] stringify: with arrayFormat: comma, properly include an explicit [] on a single-item array (#434)

    6.10.4

    • [Fix] stringify: with arrayFormat: comma, include an explicit [] on a single-item array (#441)
    • [meta] use npmignore to autogenerate an npmignore file
    • [Dev Deps] update eslint, @ljharb/eslint-config, aud, has-symbol, object-inspect, tape

    6.10.3

    • [Fix] parse: ignore __proto__ keys (#428)
    • [Robustness] stringify: avoid relying on a global undefined (#427)
    • [actions] reuse common workflows
    • [Dev Deps] update eslint, @ljharb/eslint-config, object-inspect, tape

    6.10.2

    • [Fix] stringify: actually fix cyclic references (#426)
    • [Fix] stringify: avoid encoding arrayformat comma when encodeValuesOnly = true (#424)
    • [readme] remove travis badge; add github actions/codecov badges; update URLs
    • [Docs] add note and links for coercing primitive values (#408)
    • [actions] update codecov uploader
    • [actions] update workflows
    • [Tests] clean up stringify tests slightly
    • [Dev Deps] update eslint, @ljharb/eslint-config, aud, object-inspect, safe-publish-latest, tape

    6.10.1

    • [Fix] stringify: avoid exception on repeated object values (#402)

    6.10.0

    • [New] stringify: throw on cycles, instead of an infinite loop (#395, #394, #393)
    • [New] parse: add allowSparse option for collapsing arrays with missing indices (#312)
    • [meta] fix README.md (#399)
    • [meta] only run npm run dist in publish, not install
    • [Dev Deps] update eslint, @ljharb/eslint-config, aud, has-symbols, tape
    • [Tests] fix tests on node v0.6
    • [Tests] use ljharb/actions/node/install instead of ljharb/actions/node/run
    • [Tests] Revert "[meta] ignore eclint transitive audit warning"

    6.9.7

    • [Fix] parse: ignore __proto__ keys (#428)
    • [Fix] stringify: avoid encoding arrayformat comma when encodeValuesOnly = true (#424)
    • [Robustness] stringify: avoid relying on a global undefined (#427)
    • [readme] remove travis badge; add github actions/codecov badges; update URLs
    • [Docs] add note and links for coercing primitive values (#408)
    • [Tests] clean up stringify tests slightly
    • [meta] fix README.md (#399)
    • Revert "[meta] ignore eclint transitive audit warning"

    ... (truncated)

    Commits
    • 56763c1 v6.11.0
    • ddd3e29 [readme] fix version badge
    • c313472 [New] [Fix] stringify: revert 0e903c0; add commaRoundTrip option
    • 95bc018 v6.10.5
    • 0e903c0 [Fix] stringify: with arrayFormat: comma, properly include an explicit `[...
    • ba9703c v6.10.4
    • 4e44019 [Fix] stringify: with arrayFormat: comma, include an explicit [] on a s...
    • 113b990 [Dev Deps] update object-inspect
    • c77f38f [Dev Deps] update eslint, @ljharb/eslint-config, aud, has-symbol, tape
    • 2cf45b2 [meta] use npmignore to autogenerate an npmignore file
    • Additional commits viewable in compare view

    Updates express from 4.16.4 to 4.18.2

    Release notes

    Sourced from express's releases.

    4.18.2

    4.18.1

    • Fix hanging on large stack of sync routes

    4.18.0

    ... (truncated)

    Changelog

    Sourced from express's changelog.

    4.18.2 / 2022-10-08

    4.18.1 / 2022-04-29

    • Fix hanging on large stack of sync routes

    4.18.0 / 2022-04-25

    ... (truncated)

    Commits

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
Owner
muzamil
student @ nit srinagar
muzamil
Refactoring a MERN stack react based front end starter code with a fully functioning Google Books API search engine built with RESTful API to be built with GRAPHQL API with Apollo Server.

21_MERN_GoogleBookSearchEngine Task Refactoring a MERN stack react based front end starter code with a fully functioning Google Books API search engin

Dionne Noella 5 Apr 9, 2022
Instagram MERN - Full-Stack Instgram Clone using MERN Stack and Socket.io

Instagram MERN Full-Stack Instgram Clone using MERN Stack and Socket.io Visit Now ?? ??️ Tech Stack Frontend: Backend: Realtime Communication: Cloud S

Jigar Sable 327 Jan 4, 2023
Online Marketplace Built with MERN stack (MongoDB, Express, React and Node)Online Marketplace Built with MERN stack (MongoDB, Express, React and Node)

?? Shopping App ?? Online Marketplace Built with MERN stack (MongoDB, Express, React and Node). ⚡️ ⚡️ ⚡️ Kiwi Shop ⚡️ ⚡️ ⚡️ ?? Table of contents Main

Tomiwa Adeyemi 10 Dec 23, 2022
flipkart-clone using react js express js mongo db razorpay complete e-commerce website using MERN stack client server MVC architecture redux redux-thunk ecomerce project live example

Flipkar Clone MERN stack Sijeesh Miziha's Flipkart Clone is done with top-notch features for the entrepreneur startups like Flipkart it has RazorPay I

Sijeesh Miziha 51 Dec 8, 2022
Flipkart-clone - Flipkart Clone using MERN Stack with proper File Structure and also follow MVC architecture

Flipkart Clone MERN APP Dhaval Patel's Flipkart Clone is done with top-notch fea

Dhaval Patel 52 Jan 8, 2023
A simple project to display clean and concise Covid-19 Statistics by country. ⚛️ React.js ⚛️ React Query 💅 Tailwind CSS 🔎 Google Analytics

A simple project to display clean and concise Covid-19 Statistics by country. ⚛️ React.js ⚛️ React Query ?? Tailwind CSS ?? Google Analytics

Luísa Ribeiro Bezerra 19 Oct 4, 2022
Ecommerce website built with the MERN stack with React Context API for state management

MERN-Ecommerce Ecommerce website built with the MERN stack with React Context AP

Le Van Quang 8 Nov 24, 2022
Amazon Clone Application using React JS, Context API, Firebase and Stripe with full E-Commerce Functionalities like adding to cart feature, user authorization, payment and many more.

Amazon Clone is the Fully functional Real custom made Web application that covers and entire E-commerece functionality from designing, User Authentication till Payments build using React JS, Firebase and Stripe.

Sadiq Khan 18 Aug 9, 2022
An instagram clone created with the MERN stack

Instaclone An instagram clone created with MongoDB, Express, React, and Socket.io Have a look at the live demo Tech Frontend: React State management:

Sander Moen 565 Dec 29, 2022
MERN BLOG - Fullstack open source blogging application made with MongoDB, Express, React & Nodejs (MERN)

MERN BLOG Fullstack open source blogging application made with MongoDB, Express, React & Nodejs (MERN) Configuration and Setup Key Features Technologi

Muhammet Yıldız 25 Dec 21, 2022
Twitter Clone built using React, Firebase, Material UI and React Flip Move.

Twitter Clone with ReactJS You can send a simple tweet in this app. Twitter Clone Demo Link click me for demo. Topics Material UI React Flip Move Auth

Mert Çankaya 15 Sep 19, 2022
A Spotify Clone which built with ReactJS. 3rd party API integration, user authentication, spotify API, responsive design, material-ui, react context api are used to built it.

Spotify Clone with ReactJS In this Spotify Clone application you can log in to the application with your spotify account and see your own playlist. Sp

Mert Çankaya 11 Jul 11, 2022
A Social media App built using MERN Stack

A Social media App built using MERN It is a Social media app built using mern stack. You can create an account, create posts, like and comment on post

Adarsh 9 Dec 20, 2022
Bug-Blog - A Blogging Web App built with MERN Stack

Bug Blog It's a Blogging Web App built with MERN Stack , where users can create

Aaditya 10 Oct 27, 2022
Front End for file sharing app built with the MERN Stack

zed-sharing-react Front End for file sharing app built with the MERN Stack Report Bug · Request Feature About The Project This is the Front End for Ze

Quavo 22 Sep 28, 2022
PostIt is a fully-featured social media web application, built with the MERN stack

PostIt is a fully-featured social media web application, built with the MERN stack.

Ihtasham 74 Dec 20, 2022
To Clarify - a full stack MERN web application designed to help freelance web developers keep workflow organized and to establish clarity and transparency with clients

To Clarify - a full stack MERN web application designed to help freelance web developers keep workflow organized and to establish clarity and transparency with clients

Jay 4 Apr 3, 2022
Twitter clone developed in typescript and react.

Twitter - User Feed (Clone) ?? Descrição O Twitter, é uma das maiores rede sociais atualmente . Para o desenvolvimento do clone, foi utilizado typescr

Guilherme Nono 8 Nov 22, 2022
MERN stack (MongoDB, Express, React, Node.js) blog app with Chakra UI and Redux.

MERN stack (MongoDB, Express, React, Node.js) blog app with Chakra UI and Redux.

oğulcan erişti 60 Dec 31, 2022