Hey everyone π,
Today I want to share something fun. Imagine this: you're at home with friends, the big TV is on, and instead of everyone fighting over Bluetooth controllers or passing around one gamepad⦠everyone just pulls out their phone and instantly becomes a player.
No accounts. No installs. Just scan a QR code and start mashing buttons.
That's exactly what TouchCoop enables β a tiny TypeScript library that turns this vision into reality with almost zero server hassle.
- Host runs the game on a laptop/TV-connected browser
- Up to 4 players join via QR code on their mobiles
- Touch buttons on phone β real-time input to the game via WebRTC
- Perfect for casual games: platformers, party games, local puzzles
- Not suited for low-latency games like FPS (WebRTC latency is good but not esports-level)
Quick architecture overview
Your game needs two distinct entry points (URLs):
The Match page (TV/Laptop): Creates a
Matchinstance, shows QR codes for joining, and receives player events.The Gamepad page (Phone): Opened via QR code, creates a
Playerinstance, connects, and sends touch events.
Both are just static web pages β no backend required beyond the signaling phase.
Getting started in 60 seconds
Install the library:
npm install touch-coop
1. The Match side (your game)
import { Match, PlayerEvent } from "touch-coop";
const gamePadURL = "https://your-domain.com/gamepad"; // Must be absolute URL for QR
function handlePlayerEvent(event: PlayerEvent) {
switch (event.action) {
case "JOIN":
console.log(`Player ${event.playerId} joined π`);
// Maybe spawn player avatar, play sound, etc.
break;
case "LEAVE":
console.log(`Player ${event.playerId} left π’`);
break;
case "MOVE":
console.log(`Player ${event.playerId} β ${event.button}`);
// Here you map "up", "A", "X" etc. to game actions
if (event.button === "up") jumpPlayer(event.playerId);
break;
}
}
const match = new Match(gamePadURL, handlePlayerEvent);
// Optional: custom PeerJS server for better reliability
// const match = new Match(gamePadURL, handlePlayerEvent, {
// host: 'your-peerjs-server.com',
// port: 9000,
// path: '/peerjs'
// });
// Later: match.requestNewPlayerToJoin() β returns promise with QR data/URL
Call match.requestNewPlayerToJoin() each time you want to add a slot β it gives you the join URL to turn into a QR code (many libraries can help with that).
2. The Gamepad side (React example)
import React, { useEffect, useState } from "react";
import { Player } from "touch-coop";
const player = new Player(); // Can pass custom PeerJS config too
export default function GamePad() {
const [loading, setLoading] = useState(true);
useEffect(() => {
(async () => {
try {
await player.joinMatch(); // Parses peer ID from URL query params
setLoading(false);
} catch (err) {
console.error("Failed to join", err);
}
})();
}, []);
if (loading) return <div className="text-2xl">Connecting...</div>;
return (
<div className="grid grid-cols-3 gap-4 p-8 h-screen bg-black text-white">
<button className="btn" onClick={() => player.sendMove("up")}>β</button>
<button className="btn" onClick={() => player.sendMove("left")}>β</button>
<button className="btn" onClick={() => player.sendMove("right")}>β</button>
<button className="btn col-start-2" onClick={() => player.sendMove("down")}>β</button>
<div className="col-span-3 flex justify-around mt-8">
<button className="btn bg-green-600" onClick={() => player.sendMove("A")}>A</button>
<button className="btn bg-blue-600" onClick={() => player.sendMove("B")}>B</button>
<button className="btn bg-red-600" onClick={() => player.sendMove("X")}>X</button>
<button className="btn bg-yellow-600" onClick={() => player.sendMove("Y")}>Y</button>
</div>
</div>
);
}
Live demo & try it yourself
The original project has a nice little demo:
β https://SlaneyEE.github.io/touch-coop/demos/match.html
Final thoughts
TouchCoop is a beautiful example of how far browser APIs have come: WebRTC + TypeScript + modern build tools = couch co-op without native apps or complex backends.
If you're building casual multiplayer experiences or party games give it a try.
Have you built (or are you planning to build) a couch co-op game? Drop a comment below β I'd love to hear your multiplayer war stories or see links to your projects!
Happy coding, and see you in the comments βοΈ
Top comments (0)