react-videocall, a WebRTC demo with no account and a socket.io room
WebRTC-React App for Video Calling
At a glance
- What is it?
- react-videocall is a small full-stack demo where the server hands out a unique ID per browser tab and two people connect by exchanging that ID, with socket.io carrying the signalling and webrtc-adapter smoothing over browser differences. It is a teaching project, and reading it is more useful than deploying it.
- Who is it for?
- react-videocall suits a developer who wants a working WebRTC example to read, copy or extend, especially one learning how signalling and the peer connection fit together without a media server in the way. It does not suit a production service, since there is no authentication, no TURN configuration and no signalling server of its own beyond the demo.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 20 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
No registration, one ID per tab, and a link to send
react-videocall is a WebRTC React app for video calling, and its premise is that there is no account to create. The project description is short: video call to your friend without registering, simply send your friend your auto-generated unique ID to make the call, and every time you open a new tab the server gives you a totally different unique ID.
That last detail is the design decision with the most consequences. The identifier is per tab, not per session and not per user, so the natural way to use the app is to open it in two browser tabs, read the ID from one, type it into the other, and connect. It also means there is no persistent identity, no contact list, and no history, which is exactly what a demo wants and exactly what a product cannot have.
The repository is a single package with a `client/` directory and a `server/` directory, which is the split the whole design rests on. The client is a React application bundled by webpack, and the server is an Express application. There is also a `config.js` at the root and an `app.json` for the Heroku-style deployment, plus an `eslint.config.mjs` for the flat-config ESLint setup and a `.nvmrc` pinning the Node version.
The audience is a developer. The homepage is a live demo instance on Render, and the README's own framing, with a screenshot, suggests the demo is the point. This is a reference implementation to read and learn from, or a starting point to fork, rather than a service to sign up for.
The licence is MIT, with a LICENSE.md file at the root, and the last push to the repository was on 2026-10-03.
The client and server split, and the scripts that drive it
The package manifest shows a straightforward two-part build, and the script names tell you exactly how the two halves are run.
The client is webpack-based. `build` runs a production webpack build with NODE_ENV set, using a separate production config in the `client/` directory, and `watch:client` runs webpack-dev-server with the development config. The server side is simpler: `start` is `node server/index.js`, and `watch:server` runs the same file under nodemon so the server restarts on change. The development flow is therefore two commands in two terminals, one for the API and one for the client with hot reloading.
npm install -g yarn
yarn installThat is the whole installation step, and it is a good sign for a project meant to be run on a laptop. The `lint` script is `eslint --max-warnings 0 .`, which treats any warning as a failure, and the ESLint configuration is the flat-config format with plugins for React, React Hooks, import, JSX accessibility and the stylistic rules, so the accessibility and hooks rules are enforced rather than merely available.
The React side is on React 19.3.0 with the matching react-dom, which is worth noting because the hooks lint plugin and the accessibility plugin are the ones that will complain about the code in a demo like this, and a strict setup is a reasonable default.
The styling stack is Bootstrap 5.3.8 with classnames for conditional class composition, and Sass through sass-embedded and sass-loader, with a mini-css-extract-plugin for production and style-loader for development, plus css-minimizer-webpack-plugin for the production build. The FontAwesome React packages supply the icons, and lodash 4.18.1 and prop-types are present as the remaining runtime dependencies.
The `engines` field requires Node 24, and the `.nvmrc` in the repository pins the same, so the toolchain expectation is explicit rather than implied.
socket.io for signalling, webrtc-adapter for the browser gaps
The two dependencies that explain the architecture are socket.io and webrtc-adapter, and they do two different jobs.
WebRTC needs a signalling channel: the two browsers have to exchange session descriptions and ICE candidates before the peer connection can be established, and they cannot do that over the media path itself. In this project that channel is a WebSocket, with socket.io on the server at 4.8.4 and socket.io-client on the client at the same version. The server issues the unique ID, the client reports it, and the signalling messages that set up the call travel over the socket.
The second dependency, webrtc-adapter at 9.0.6, is the compatibility shim. It normalises the differences between browser implementations of the WebRTC API, so the same code can call `getUserMedia` and create a peer connection without branching per browser. That is the difference between a demo that works in one browser and one that works in the browsers people actually have.
The split is visible in the scripts as well. `watch:client` serves the client on port 9000 according to the README, while the server runs separately, so during development the client talks to the API across the loopback interface and the socket.io connection is a second channel over the same network boundary.
What the project does not have is a media server. There is no SFU, no MCU and no TURN configuration in the repository layout or the dependency list. That is entirely reasonable for a two-person call, because a direct peer connection between two browsers works when both are reachable, and it means the call media never touches the server. The consequence is that the deployment is much simpler and the server is only a rendezvous point, but the call quality depends on whether the two peers can reach each other, and there is no relay to fall back on when they cannot.
The server is Express 5.2.1, which is the only web framework in the dependency list, and the app.json file at the root is the manifest shape that Heroku-style platforms consume.
Deploying to Render, and the manual path
The deployment section offers three routes, and the recommended one is a free tier of a managed platform.
Render is listed first, as free and recommended, with a deploy button pointing at the `production` branch of the repository rather than the default branch. That detail is worth noticing: the branch used for deployment is not the branch you develop on.
Heroku is the second option, and its button links to the same render.com deploy URL, which reads as a copy and paste slip in the README rather than a working Heroku path.
The custom route is the third, and it is the three-step sequence you would use on your own machine or your own host.
# Install dependencies
yarn install
# Build front-end assets
yarn build
# Run server
yarn startThe order matters and is the whole point of the split. The client build produces static assets that the Express server then serves, and `yarn start` runs the server with the built bundle in place. A deployment that skips `yarn build` gives you a server with no client to serve.
For the local development loop, the README documents two commands.
yarn watch:serveryarn watch:clientThe first runs the server under nodemon and the second runs webpack-dev-server, which the README notes serves at http://localhost:9000.
One thing the documentation does not discuss is the signalling configuration for a deployed instance. The socket.io server has to be reachable by both peers, and both peers have to be able to reach the STUN or TURN server that the WebRTC stack uses to discover addresses. Neither is visible in the repository listing or the dependency set, which suggests both are handled by the deployment platform's environment rather than by configuration in the code, and that is something to confirm before you rely on a deployed instance.
What this demo does not give you
It is worth being blunt about the gaps, because the list is what turns this from a demo into a product project, and the gaps are substantial.
There is no authentication of any kind. The unique ID is generated by the server per tab, and whoever holds it can join the call. That is acceptable for a demo where you hand the ID to a friend over a message, and it is unacceptable for anything else, because an ID is a bearer token with no expiry and no scope.
There is no TURN server, and no configuration surface for one in the repository. Direct peer-to-peer media works when both peers have a routable path to each other, and behind symmetric NAT on both sides it does not work at all. The webrtc-adapter dependency smooths over API differences, not network topology.
There is no room management beyond a single call, no call history, no device selection UI beyond whatever the client implements, no screen sharing, and no recording.
The video is peer to peer with no server in the path, which has a consequence for privacy that is easy to miss. The media never reaches the server, but the signalling does, and the signalling includes the SDP and the ICE candidates, which describe the network topology of both peers. A server operator sees that. The documentation does not discuss it.
The dependencies are also pinned tightly. React 19.3.0, webpack 5.111.1, Babel 8.0.6, Express 5.2.1, socket.io 4.8.4, all exact versions with no caret or tilde. That is a defensible choice for a demo whose lockfile is committed, and it means you will be updating versions by hand rather than by a range.
There are no tagged releases in the repository, and the version in the manifest is 1.9.0 for an application that is not published as a library. So the practical upgrade story is: read the diff, change the pinned versions, run the two dev commands and check that the call still connects.
Editorial conclusion
react-videocall suits a developer who wants a working WebRTC example to read, copy or extend, especially one learning how signalling and the peer connection fit together without a media server in the way. It does not suit a production service, since there is no authentication, no TURN configuration and no signalling server of its own beyond the demo. Verify first that a STUN or TURN server is reachable from your deployment environment, that the WebSocket connection survives whatever proxy sits in front of your app, and that the licence and the deployment terms of the free hosting the documentation points to match what you intend to do with the code.
Frequently asked questions
How do I start a video call with react-videocall?
Open the app, and the server gives you a unique ID for that tab. Send that ID to the other person, and entering it in their tab connects the two of them. The documentation stresses that every new tab gets a completely different unique ID.
How do I install and run react-videocall locally?
Run npm install -g yarn and then yarn install. For development use yarn watch:server to run the server under nodemon and yarn watch:client to run webpack-dev-server, which the README says serves at http://localhost:9000.
How is the call set up between two browsers?
The server assigns a unique ID per tab and socket.io carries the WebRTC signalling, while webrtc-adapter normalises the browser differences in the WebRTC API. The media path is peer to peer, with no media server in the repository.
How do I deploy react-videocall to my own host?
Follow the custom route: yarn install to install dependencies, yarn build to build the front-end assets, then yarn start to run the server, which is node server/index.js. The README also offers a one-click Render deployment from the production branch.
Is react-videocall suitable for production use?
Not as it stands. There is no authentication, the unique ID is a bearer token with no expiry, there is no TURN server configuration in the repository, and the project publishes no releases, so it is best read as a reference implementation to extend rather than a service to run as is.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/nguymin4-react-videocall)Was this useful?