How to Use Svelte and Go to Build a Video Chat App
Time to read:
The internet has made the world a much smaller place. Not only can you chat with your loved ones in real-time, but with video you can also see them and experience an extra level of interaction that words alone fail to capture.
In this tutorial, I will show you how simple it is to build a video chat app using Twilio Video, using Svelte for the frontend and Go for the backend.
Prerequisites
To follow along, you will need the following:
- A Twilio account (a free account works fine).
- Go 1.24 or newer.
- Node.js 20.19 or newer (or 22+) and npm. The current Vite tooling requires one of these versions.
- Git.
- Basic knowledge of Go and Svelte.
How the application works
Before writing any code, it helps to understand the flow. The application has two parts, a Go REST API and a Svelte single-page app. A video call comes together in four steps:
- The frontend presents a form where the user enters a room name.
- The room name is sent to the backend.
- The backend generates a Twilio Access Token with a video grant for that room.
- The frontend uses the token to connect to the Twilio Video room and attaches the video tracks to the page.
In this tutorial, you will build the backend first, then the frontend that talks to it. Let’s get started!
Setting up the backend
Start by creating a project folder with a backend folder inside it, then initialize a Go module. To do this, run the following commands.
Next, add the three dependencies the backend relies on: a CORS handler so the browser can call the API, GoDotEnv to load environment variables, and the Twilio Go Helper Library to build the Access Token.
Next, create a new file named .env in the backend folder. This file is a placeholder template that holds no secrets, so it is safe to commit to version control. Paste the following code into it.
Your real credentials will go in a separate .env.local file, which is the file the application actually reads. Before you create it, add a .gitignore in the backend folder so that .env.local is never committed.
Now, create your local copy of the template with the following command. Because .env.local is git-ignored, your real credentials stay out of version control.
You will fill in the values in a moment. Your Account SID is on the Twilio Console dashboard. Next, create a new API Key which will be used for authentication to the Twilio Video API. In the Twilio Console, go to Settings > API keys & auth tokens, create a Standard key, and copy the SID and Secret, as the secret is only shown once.
Paste those three values into backend/.env.local:
With the credentials in place, you can write the code that mints a token. Create a new folder named helper in the backend folder. In the new helper folder, create a new file named token.go and add the following code to it.
The GenerateToken function reads your Twilio credentials from the environment, builds an Access Token, attaches a VideoGrant scoped to the requested room, and signs it into a JWT. The identity helper gives each participant a unique, random identity using crypto/rand, so two people in the same room never collide.
Next, the backend needs to validate the room name coming from the frontend. To do this, create a new folder named model in the backend folder, and in that new folder create a file named room.go. Then, paste the following code into the new file.
The Room struct maps the incoming JSON payload, and Validate enforces a simple rule: room names must be at least six characters long.
All that is left is a main() function to serve as the entry point for the application and handle incoming requests. In the backend folder, create a new file named main.go and paste the following code into it.
This loads the environment variables, wraps the handler in the default CORS middleware so the browser can reach it, and starts an HTTP server on port 8000. For each POST request, roomHandler decodes the room name, validates it, and returns either a 400 with an error message or a signed access token as JSON.
Start the backend to confirm it runs.
You should see “Starting server at port 8000”. Leave it running and open a second terminal for the frontend.
Setting up the frontend
For the frontend, scaffold a new Svelte project with Vite, the current official tooling for Svelte apps. From the project root (the svelte-go-video-chat folder), run the following command. The --template svelte flag selects the Svelte project for you, so the command runs without any prompts.
This creates a frontend folder with a ready-to-run Svelte 5 project. Move into it and install the dependencies.
Next, install the three packages this app needs: twilio-video to manage the video connection, axios to call the backend, and izitoast to display notifications.
With the project scaffolded, create a new file named src/Helper.js and add the following code. This module handles all the communication with Twilio Video.
connectToRoom first requests an access token from the backend, then calls connect() to join the room and createLocalVideoTrack() to capture the user's camera. It attaches the local track to the page, then wires up the participantConnected and trackSubscribed events so that when someone else joins, their video track is attached too. The final loop over room.participants handles anyone who was already in the room when you joined. These are the core Twilio Video client calls, and they are unchanged from earlier versions of the SDK.
Now, update frontend/src/App.svelte to match the following code.
The component shows a form that accepts a room name. When it is submitted, handleSubmit reads the room name, hides the form by setting hasJoinedRoom, and calls connectToRoom, passing in the #remote-media container where the video tracks are attached. The import at the top pulls in the iziToast styles so the notifications are styled correctly.
Two small housekeeping steps finish the setup. The Vite scaffold generates src/main.js to bootstrap the app, and it already uses Svelte 5's mount() API, so there is nothing to change.
Finally, open index.html and set the <title> to something meaningful such as “Svelte Go Twilio Video Chat App”, and clear out the demo markup in src/app.css if you would like a blank slate. The scaffold also ships a src/lib/Counter.svelte and some assets from the starter template that this app does not use, so you can safely delete them.
Testing the application
With the Go backend still running on port 8000, start the frontend dev server.
Vite serves the app at http://localhost:5173 by default (if that port is taken, it prints the one it chose). Open the app in two browser tabs, enter the same room name (at least six characters) in both, and submit. Your browser will ask for camera and microphone permissions the first time, allow them, and each tab will show both the local and remote video streams.
Conclusion
There you have it, without writing any code for permissions, RTC (Real Time Communication) or data streaming, you have an application capable of handling all those and even more.
In addition to video streaming, the Twilio Video SDK provides functionality for muting audio, recording video chats and displaying camera previews before joining a room. You can view the documentation here.
I'm excited to see you build the next big thing in video communication.
You can review the final codebase for this article on GitHub. Until next time!
Additional resources
- Twilio Video documentation: the full reference for the Video API.
- Twilio Video JavaScript getting started guide: a deeper look at the client SDK used here.
- twilio-go: the Twilio Go Helper Library used in the backend.
- Svelte documentation: learn more about the frontend framework.
- Go documentation: learn more about the backend language.
Related Posts
Related Resources
Twilio Docs
From APIs to SDKs to sample apps
API reference documentation, SDKs, helper libraries, quickstarts, and tutorials for your language and platform.
Resource Center
The latest ebooks, industry reports, and webinars
Learn from customer engagement experts to improve your own communication.
Ahoy
Twilio's developer community hub
Best practices, code samples, and inspiration to build communications and digital engagement experiences.