Skip to contentSkip to navigationSkip to topbar
Rate this page:
On this page

Using a Front-End Framework with Twilio Serverless

Additionally to using Twilio Assets to host audio files for your phone calls or files for shared logic between your Twilio Functions you can also use it to serve front-end web assets such as HTML, JS and CSS files.

In this guide we'll talk about how you can use the Serverless Toolkit to use front-end frameworks to build you web assets. As an example we'll be using React(link takes you to an external page) as a front-end framework but you can use any common framework including Vue(link takes you to an external page) and Angular(link takes you to an external page).


setup page anchor

Setup your Twilio Serverless project

setup-your-twilio-serverless-project page anchor

If you don't already have an existing project using the Serverless Toolkit, go ahead and create one by following the instructions in our Getting Started guide. Otherwise, keep reading.

In this guide we'll be using Parcel(link takes you to an external page) as our build tool of choice but you can apply similar steps to Webpack(link takes you to an external page) or other bundlers.

Make sure to install your bundler tool in the devDependencies section of your package.json.

To install Parcel run:

npm install parcel-bundler --save-dev

Define your project structure

define-your-project-structure page anchor

By default a project created with the Serverless Toolkit will contain a functions/ and an assets/ directory. In our case we'll want to keep the two directories but we'll also add two new directories:

  • src/ will contain our front-end code that we'll end up passing through the Parcel Bundler
  • dist/ will serve as the source of truth for the assets that we'll deploy. In our case this will be a combination of the bundled assets from src/ and the static files from the assets/ directory.

Create the src/ directory and add an index.html file to it as this will serve as the entry point for our bundler.

This is where you'll reference other files that should be bundled such as stylesheets or JavaScript files. For more information, make sure to check out the Parcel documentation(link takes you to an external page).

Since the dist/ directory contains bundled files it does not make sense to version control this directory. Instead make sure to add it to your .gitignore file at the root of your project.


Install other helpful tools

install-other-helpful-tools page anchor

We'll be using two other tools:

Install the two dependencies by running:

npm install concurrently ncp --save-dev

Configure the Serverless Toolkit

configure-the-serverless-toolkit page anchor

By default the Serverless Toolkit will use the assets/ directory to serve and deploy Twilio Assets.

You can modify this behavior by using the --assets-folder flag but the easier way is by creating/modifying your .twilioserverlessrc file at the root of your project the following way:

"commands": {},
"environments": {},
"projects": {},
// "assets": true /* Upload assets. Can be turned off with --no-assets */,
"assetsFolder": "dist" /* Specific folder name to be used for static assets */,
// ..

Next we need to define a couple of "scripts" inside our package.json to make executing the right steps easier.

Modify the scripts section of your package.json the following way:

"scripts": {
"prebuild": "rimraf dist"
"build": "parcel build src/index.html -d dist",
"postbuild": "ncp assets dist",
"predeploy": "npm run build",
"deploy": "twilio-run deploy",
"start:web": "parcel watch src/index.html -d dist",
"start:twilio": "twilio-run",
"prestart": "ncp assets dist",
"start": "concurrently npm:start:web npm:start:twilio"

This way you'll have three distinct commands:

  • npm start will start the build server for Parcel and serve all Assets and Functions locally using twilio-run
  • npm run build to build all front-end assets and copy over all static files from assets/
  • npm run deploy will run npm run build and take all files in dist/ and deploy them together with all Functions from functions/ to Twilio Functions.


If you are using twilio serverless:deploy to deploy your application instead of twilio-run you have to manually run npm run build first and then can normally deploy using twilio serverless:deploy.

Start building your front-end

start-building-your-front-end page anchor

Now that we set up our build chain you can start developing your project.

Most things should work as you are used to but there are a few things to keep in mind.

All dependencies for your UI should be installed as devDependencies unless they are also used from within your Functions. For example, let's say we want to use React with Twilio's Paste Design System(link takes you to an external page). We'd install the dependencies the following way:

npm install react react-dom prop-types @twilio-paste/core @twilio-paste/icons --save-dev

Note the --save-dev at the end. If you are using yarn or pnpm both of them support equivalent flags to store dependencies as devDependencies.

If you do not install them as devDependencies but as dependencies instead, they'll be installed in your Twilio Functions deployment which increased deployment times and might cause other unintended side effects including failed builds.

When you run npm run deploy or twilio serverless:deploy the tool will automatically deploy everything in the dist/ folder but nothing else. Meaning if you are building your output files with file hashes in the name (e.g. main.a124bfc.js) and the build changes that hash to a different one (e.g. main.a12222f.js) and you deleted the dist/ folder prior to building (default in the scripts above) this will result in main.a124bfc.js to not be served anymore post deployment. The Serverless Toolkit currently does not support additive deployments that would support both versions to be available.

On the flip-side keeping your dist/ folder as lean as possible will reduce the deployment time.

With the setup described above you should be able to call any of your Functions that exist in the functions/ directory by specifying the absolute path of them. For example for a Function with the file functions/token.js you can make an HTTP request from within your front-end to /token.

For example:

.then(response => response.json())
.then(data => {

We talked about "static" assets above? What are those and why are we keeping those separately in a assets/. With static assets in this case we mean any file we don't want to have processed by our build tooling. Common types of such assets could be media files — for example an mp3 file that you are referencing in the TwiML for your Twilio Voice call — or a private JavaScript module that you are referencing for from one of your Twilio Functions to store shared logic. In general private assets are likely going to be static assets that you might want to store in the assets/ directory.

At the current moment Twilio Assets does not support the following two features that you might have to consider when building your front-end on Twilio Serverless:

  1. No URL fallbacks/redirects meaning you cannot use tools such as react-router unless you are operating them in a hash-based routing mechanism. You'll always have to serve to specify the full URL. The only current exception is if you have a file with the path /assets/index.html you can use / to reference the same file. In our case this means that you'd have to have Parcel output a file in the directory dist/assets/index.html which then, once deployed, will be available both at https://<service_name>-<number>-<environment_suffix> and https://<service_name>-<number>-<environment_suffix> .
  2. No built-in build system you have to build all the respective files and trigger your deployment either locally or using your own CI/CD system of choice. Check out the following guide on using Twilio Serverless from CI/CD for more guidance .

Rate this page: