TypeScript backend
TypeScript backend support is in alpha
The core of Reboot — durable state, transactions, workflows, tasks,
and the standard library — works in
both Python and TypeScript, but some features are currently
Python-only, including MCP UIs,
UI methods, the
built-in OAuth sign-in flow — and therefore
User auto-construction — and
durable agents. If you don't have a strong preference for
TypeScript, prefer
starting with Python.
- Set up your app foldermkdir reboot-chat-room && cd reboot-chat-room
- Install Rebootnpm init -y && npm pkg set type="module" && npm install @reboot-dev/reboot zod@^4.0.0 && npx tsc --init --sourceMap --declaration --moduleResolution node --target es2020 --rootDir . --outDir dist
- Make sure Docker is runningdocker ps
- Define your API using Zodmkdir -p ./api/chat_room/v1 && touch ./api/chat_room/v1/chat_room.ts
- Define your durable state data types and operations// ./api/chat_room/v1/chat_room.tsimport { reader, writer } from "@reboot-dev/reboot-api";import { z } from "zod/v4";export const ChatRoom = {state: {messages: z.array(z.string()).default(() => []).meta({ tag: 1 }),},methods: {messages: reader({request: {},response: {messages: z.array(z.string()).meta({ tag: 1 }),},}),send: writer({request: {message: z.string().meta({ tag: 1 }),},response: {},}),},};export const api = {ChatRoom,};
- Create
.tsimplementation filemkdir -p ./backend/src && touch ./backend/src/chat_room_servicer.ts - Implement
ChatRoomServicer- Object literal
- Class
// ./backend/src/chat_room_servicer.tsimport { ReaderContext, WriterContext } from "@reboot-dev/reboot";import { ChatRoom } from "../../api/chat_room/v1/chat_room_rbt.js";export const chatRoomServicer = ChatRoom.servicer({messages: async (context: ReaderContext,state: ChatRoom.State,request: ChatRoom.MessagesRequest): Promise<ChatRoom.MessagesResponse> => {return { messages: state.messages };},send: async (context: WriterContext,state: ChatRoom.State,request: ChatRoom.SendRequest): Promise<[ChatRoom.State, ChatRoom.SendResponse]> => {state.messages.push(request.message);return [state, {}];},});// ./backend/src/chat_room_servicer.tsimport { ReaderContext, WriterContext } from "@reboot-dev/reboot";import { ChatRoom } from "../../api/chat_room/v1/chat_room_rbt.js";export class ChatRoomServicer extends ChatRoom.Servicer {async messages(context: ReaderContext,request: ChatRoom.MessagesRequest): Promise<ChatRoom.MessagesResponse> {return { messages: this.state.messages };}async send(context: WriterContext,request: ChatRoom.SendRequest): Promise<ChatRoom.SendResponse> {this.state.messages.push(request.message);return {};}} - Create a
mainentrypointtouch ./backend/src/main.ts - Implement
main.ts- Object literal
- Class
// ./backend/src/main.tsimport { Application, InitializeContext } from "@reboot-dev/reboot";import { ChatRoom } from "../../api/chat_room/v1/chat_room_rbt.js";import { chatRoomServicer } from "./chat_room_servicer.js";const initialize = async (context: InitializeContext) => {const chatRoom = ChatRoom.ref("reboot-chat-room");await chatRoom.send(context, { message: "Hello, World!" });};new Application({servicers: [chatRoomServicer],initialize,}).run();// ./backend/src/main.tsimport { Application, InitializeContext } from "@reboot-dev/reboot";import { ChatRoom } from "../../api/chat_room/v1/chat_room_rbt.js";import { ChatRoomServicer } from "./chat_room_servicer.js";const initialize = async (context: InitializeContext) => {const chatRoom = ChatRoom.ref("reboot-chat-room");await chatRoom.send(context, { message: "Hello, World!" });};new Application({servicers: [ChatRoomServicer],initialize,}).run(); - Create an
.rbtrcfiletouch .rbtrc - Add necessary flags to your
.rbtrcfile# .rbtrcgenerate api/generate --nodejs=api/dev run --application-name=chat-roomdev run --watch=backend/src/**/*.tsdev run --nodejsdev run --application=backend/src/main.ts - Run your appnpx rbt dev run
- Query your appcurl -XPOST http://localhost:9991/chat_room.v1.ChatRoomMethods/Messages \-H "x-reboot-state-ref:chat_room.v1.ChatRoom:reboot-chat-room"
Next steps
Well done! You made it!
This example is somewhat contrived: it creates just one instance of
your ChatRoom data type, but in practice you are free to make as many
of these as you like!
Check out these links to continue your exploration:
- Build a React frontend - create a React frontend that connects to your backend and displays your messages in real-time.
- Authenticate callers - verify bearer tokens
with a
TokenVerifierand decide who may call what with authorizers. - Learn about transactions - so far,
you've seen
readerandwritermethods, but Reboot's power extends totransactions. Learn abouttransactionsand all of the other method kinds here. - Join us on Discord - to ask questions and let us know what you think!
Hopefully, your wheels are starting to spin thinking of all of the possibilities!