PartyKit is the platform for real-time, multiplayer, and AI applications. Build collaborative features with WebSockets, state machines, and AI in minutes.
Party Server: Stateful WebSocket
// party/main.ts
import type { Party, Connection, ConnectionContext } from "partykit/server";
export default class ScrapingRoom implements Party.Server {
connections: Map<string, Connection> = new Map();
products: Product[] = [];
onConnect(conn: Connection, ctx: ConnectionContext) {
// Send current state to new connection
conn.send(JSON.stringify({ type: "init", products: this.products }));
}
onMessage(message: string, sender: Connection) {
const data = JSON.parse(message);
switch (data.type) {
case "add-product":
this.products.push(data.product);
// Broadcast to ALL connected clients
this.room.broadcast(JSON.stringify({
type: "product-added",
product: data.product,
}));
break;
case "update-price":
const product = this.products.find(p => p.id === data.id);
if (product) product.price = data.price;
this.room.broadcast(JSON.stringify({
type: "price-updated",
id: data.id,
price: data.price,
}));
break;
}
}
onClose(conn: Connection) {
this.connections.delete(conn.id);
}
}
Client: Connect and Collaborate
import PartySocket from "partysocket";
const ws = new PartySocket({
host: "my-project.username.partykit.dev",
room: "scraping-dashboard",
});
ws.addEventListener("message", (event) => {
const data = JSON.parse(event.data);
switch (data.type) {
case "init": setProducts(data.products); break;
case "product-added": addProduct(data.product); break;
case "price-updated": updatePrice(data.id, data.price); break;
}
});
// Send updates
ws.send(JSON.stringify({
type: "add-product",
product: { id: "123", title: "Widget", price: 29.99 },
}));
React Hook
import usePartySocket from "partysocket/react";
function Dashboard() {
const [products, setProducts] = useState([]);
const ws = usePartySocket({
host: "my-project.username.partykit.dev",
room: "dashboard",
onMessage(event) {
const data = JSON.parse(event.data);
if (data.type === "init") setProducts(data.products);
if (data.type === "product-added") setProducts(prev => [...prev, data.product]);
},
});
return products.map(p => <ProductCard key={p.id} product={p} />);
}
Cron and Alarms
export default class ScrapingScheduler implements Party.Server {
async onAlarm() {
// Runs on schedule
const products = await scrapeProducts();
this.room.broadcast(JSON.stringify({ type: "scraped", products }));
// Schedule next alarm
this.room.storage.setAlarm(Date.now() + 60 * 60 * 1000); // 1 hour
}
onConnect() {
// Start scheduling on first connection
this.room.storage.setAlarm(Date.now() + 1000);
}
}
AI Integration
import { AI } from "partykit/ai";
export default class AIRoom implements Party.Server {
ai = new AI(this.room);
async onMessage(message: string) {
const response = await this.ai.run("@cf/meta/llama-3-8b-instruct", {
messages: [{ role: "user", content: message }],
});
this.room.broadcast(JSON.stringify({ type: "ai-response", text: response }));
}
}
Build collaborative data apps? My Apify tools + PartyKit = real-time team dashboards.
Custom real-time solution? Email spinov001@gmail.com
Top comments (0)