Streamline Your Flex Plugin & Functions Development Using VS Code

May 08, 2020
Written by

Flex Functions VS Code

Want to see Twilio Flex in action? Check out our interactive demo.

Ready to start building your contact center? We're offering $5,000 worth of free Flex Hours to help you get started. Sign up and start building with Twilio Flex!

If you’re a developer building plugins for Twilio Flex, and you have corresponding Twilio Functions that you often build in conjunction with those plugins, then being able to efficiently debug and deploy your code can give you the power to build and iterate with great efficiency.

Over the past year, Twilio has invested in providing a CLI and a Serverless module that allow for streamlined debugging and deploying of your plugins and functions. In this blog post, I’ll show you exactly how to take full advantage of these existing capabilities.

We’re going to be covering a very basic “hello-world” example, but the foundation you will have for debugging and deploying, both in the structure of your project as well as your knowledge of how all the pieces work together, will empower you to iterate on more complex examples without being bogged down by your development setup.

The instructions below are meant to be followed in order, so please consider this as you get your setup ready for debugging.

Get your local environment ready

In order to take full advantage of debugging and deployment capabilities, you must first get your local environment prepared.

VS Code and Dependencies

There are quite a few points of failure when attempting to debug locally. This is because there are so many dependencies required to not only get your debugging setup working properly, but to keep it working properly as browser versions, IDEs, node package versions, etc change and get updated over time. Given this complexity of interdependencies, we’re going to focus on using VS Code as our IDE and with a very specific set of instructions to follow. Doing so will help mitigate the likelihood of your debugging setup getting out of sync and causing more problems. That said, given the reality of changing dependencies and the difficulty controlling every one of those dependencies, Your mileage may vary with respect to this specific setup as time goes on and you will need to adapt your dependencies as appropriate.

As of today, here’s the version information for the core dependencies used in this blog for debugging locally:

You are certainly free to use your own IDE and/or different versions of dependencies that ones listed above, but that likely will require you make some slight deviations from the debugging instructions in this blog.

Install Ngrok

Ngrok exposes local servers behind NATs and firewalls to the public internet over secure tunnels, which in this case will allow you to test HTTP/S calls between your hosted Twilio Flex instance and your local server. For the purposes of this blog, we need this so that we can call or text our flex number and route it to our local server for debugging our functions. Go ahead and download and install ngrok.

Installing the Twilio CLI and Serverless plugins

Open a terminal window from within VS Code and run these two commands in succession:

npm install twilio-cli -g

twilio plugins:install @twilio-labs/plugin-serverless

Initialize your Flex Plugin and Twilio Functions

Whether you are coding from scratch or already have a project in the works, there are separate initialization steps that are required for Flex plugins and Twilio Functions. These initializations build folder structures and add dependencies, so we simply need to make sure a single project can support the combined folder structure and dependencies.


This Plugin Quickstart is the best resource to get started with Flex Plugins. As mentioned in the quickstart, before you can start creating Flex plugins, you'll need a few things in place.

Create your Flex Plugin

Create-flex-plugin is the NPM package we will use to create the Flex Plugin and generate your baseline project folder structure. For this blog, we’ll create a plugin called myFlexPlugin. These 2 steps will set this up:

  1. Install the NPM package (use -g if you want global install): 

    npm install create-flex-plugin
  2. Initialize the Flex Plugin: 

    create-flex-plugin plugin-myFlexPlugin --install

VS Code create a Flex plugin

The resulting project folder structure can now serve as a baseline for your project.

Create your Twilio Functions

To get your Twilio Functions created, from a terminal window make sure you’re in the “plugin-myFlexPlugin” folder. Then run:

twilio serverless:init default

which will create the appropriate folder structure for you automatically. It should look like this:

Create Twilio Functions

The “default” folder naming convention will help keep our functions tied to our flex plugin when we deploy

Local Debugging

Prep your VS Code Instance to Debug your Plugin and Functions Code

If you haven’t already done so, open your project in VS Code and get 2 embedded terminal windows open, one at the plugin root folder where we’ll be debugging/deploying the Flex Plugin, and the other in the “default” folder where we’ll be debugging/deploying our Functions.

Opening two terminals in VS Code for Functions development

Also, you’ll want to make sure your VS Code Auto-Attach feature is turned on so you can set and hit breakpoints.

Functions Debugging

The serverless toolkit provides powerful flags when starting a local development server. These flags are spelled out in detail on the GitHub page and are worth reviewing before you proceed further.

At a minimum, you must use the --ngrok and --inspect flags to properly debug, but there are additional flags commonly used like specifying a port, whether to use local environment variables, make live updates to your functions without needing to restart the server, etc. For this demo, we’ll be using flags for all of the examples we just mentioned.

Before you start your debugging, you must stop all Ngrok processes currently running. If there’s an existing process running, you won’t be able to start the debugger!

(If you need help getting ngrok up and running, see the Expose a local web server to the internet documentation).

Run the following command from your terminal (make sure you are in the “default” folder or your functions won’t be loaded properly):

twilio serverless:start --ngrok=[your subdomain] --inspect="" --port=3000 

Alternatively to the --ngrok=[your subdomain], if you do not have a subdomain, you can use --ngrok="" and it will generate a random subdomain for you.

The debugger should start and attach immediately (the status bar at the bottom will turn orange). The console should also log your available functions and assets as well as the URL to your ngrok inspector.

Viewing the ngrok inspector for Functions development

Configure your Flex Project’s Studio Flow for Debugging Locally

Open the Twilio Console in your web browser and navigate to your Studio Flow (In this case, we'll use the “Voice IVR” Flow that gets created by default for all Flex projects). Update the “HOLD MUSIC TWIML URL” on the “Send to Flex” widget to point to your ngrok subdomain or randomly generated domain from the previous step.  In this example, we’ve specified the path “hello-world” because we will designate this to point to our “hello-world.js” function that was auto-generated from our serverless:init step above.

Adding Studio widgets to the canvas

Now the phone number hooked up to your Studio Flow is pointing to your local debugging instance that you started in the previous step, and thus you can now refresh your debugger and set breakpoints in your functions!

I demonstrate this here by setting a breakpoint in my hello-world.js function locally and then placing an inbound call to my Flex number....

Flex Dial out from VS Code

You’ve now unleashed the power of debugging your functions in VS Code! Now it’s time to complement that capability with your Flex Plugin code!

Plugin Debugging

Before going further, make sure you’ve installed the Chrome VS Code extension and setup your launch.json. (skip the “Start Debugging” and below sections of this doc as we’ll be covering that in this blog post). Once you’ve created the launch.json, change the “url” to http://localhost:3001 since we’ll be using port 3001 for our Flex Plugin.

In your VS Code instance, flip over to your other terminal window and make sure you’re in the root plugin folder (in this case plugin-myFlexPlugin).

From your terminal, run:

npm run build 

This builds your Flex Plugin and places it in a “build” folder under the root plugin folder. The plugin code is minified but contains a corresponding Source Map that will be very important to our debugging, as it essentially reconstructs the source code in original, non-minified form so you can debug and set breakpoints effectively in your plugin code (including all associated scripts that were used to build the plugin).

With your launch.json ready and your plugin built, we can now start our local instance of Flex running our plugin by running npm start , which will start Flex on port 3001 or the next open port (recall you are already using port 3000 for debugging your functions).

If this is your first time running this Flex Plugin locally, you’ll be prompted to login to your Twilio account. Login and ensure your working Project is your Flex project.

Starting a Flex Plugin in VS Code

Now that your Flex Plugin is running locally on port 3001, you can IGNORE the browser window that was just launched because the debugger will launch a new browser window for us.

We can start our debugger by launching an debugging instance of Chrome from VS Code using the launch.json settings we created previously. Take note of the “Loaded Scripts” section in VS Code as this is where our Flex Plugin Source Map will show up and allow us to set breakpoints from within it. As an example, set a breakpoint tied to your props.isOpen condition in your CustomTaskList.jsx component, refresh your debugger, and you should hit the breakpoint.

New browser for Flex launched from VS Code

Deploy via the Twilio CLI

Congratulations – you've now mastered all the basics of debugging a Functions-linked Flex plugin. Now that you've mastered the basics of debugging locally, let's walk through how you can deploy using the Twilio CLI.

Before we released the Twilio CLI in 2019, the only way to deploy Functions and Flex Plugins was to manually type and upload them respectively in the Twilio Console. This was problematic because there was no real organization or lifecycle management available, and you were forced to debug your functions using console.log() statements in the Console editor.

Now with the CLI, you have all the tools to manage your project organization and lifecycle at your fingertips from the development tools you love most.

Plugin Deployment

When you deploy a Flex plugin via the CLI for the first time, it creates a containerized structure called a “Service” and labels that container as “default”, and an “Environment” that encapsulates your functions and assets. You can use the Flex Plugin Builder and the Twilio CLI to deploy the Plugin and associated Functions in 2 steps.

The first step is to deploy the Plugin. From your VS Code terminal at the plugin root folder, run the following command, replacing the AccountSID and AuthToken with those from your Flex Project.

TWILIO_ACCOUNT_SID=[your account sid] TWILIO_AUTH_TOKEN=[your auth token] npm run deploy 

Once the deployment is finished, navigate to the Twilio Console -> Functions -> API  to get a look at what the deployment created. You will notice the Service and Environment containers and the associated plugin loaded as an Asset. Notice that no Functions were deployed.  

Example Flex deployment created from VS Code

Function Deployment

After deploying your plugin, you can proceed with deploying your functions. Head over to your VS Code terminal. Make sure you’re under the “default” folder and run twilio serverless:deploy --service-name=default --override-existing-project --account-sid=[your account sid] --auth-token=[your auth token]

The combination of  --service-name=default --override-existing-project flags allow you to deploy your functions to the existing service container that was created with the plugin deployment. A new Environment will be created consistent with the process as outlined here, and your functions (and assets) will be deployed in association with that Environment.

New environment created for Flex from VS Code

Toggle your Flex Project’s Studio Flow to use your new Functions Domain

You’ve now deployed your Flex Plugin and all associated Functions and Assets, and you want to give the deployment a spin to make sure it works now in a Twilio-hosted environment.

First launch Flex (as an Admin) from the Twilio Console and validate that your plugin is associated with your Flex instance

Validating your Flex plugin is associated with a Flex Instance

Once that’s good to go, all you have left to do is to connect your Studio Flow to your deployed function code.  To do so, you’ll need to reconfigure the HOLD MUSIC TWIML URL. Replace the Ngrok domain you used for debugging locally with your new functions domain (in your case it will be something like default-[your prefix] Make sure to keep the hello-world path).  

Now you can place an inbound call to your Flex number like you did before and test your Flex Plugin and associated Functions - this time fully hosted on Twilio!

Beyond “Hello-World”

Build a Real-World Implementation

So you want to take this “hello-world” Plugin to the next level, hooking up TaskRouter and routing to real agents, and maybe instead of using functions as core dependency on your initial call flow, you want to use functions in supplemental fashion by calling them directly from your Flex Plugin React Components.

The good news is that you’ve already done all the heavy lifting to create a core foundation for debugging and deploying. Certainly there are an infinite number of permutations for how you can use Functions with Flex Plugins that may require you make subtle tweaks to your setup and configuration, but you’ll be much better equipped to adjust to those scenarios with a streamlined debugging setup.

That said, there are some common tips and tricks we’ve seen that we’d like to cover that you may run into along your coding journey:

- Signing into Twilio vs SSO Setup for Debugging - When you launch a chrome debugging instance from VS Code while not yet authenticated, Twilio will prompt you to login either via SSO or as a Flex Admin. In this blog we assume login as Flex Admin in which you authenticate through the Twilio login portal, but you can certainly use the SSO option if your organization has SSO configured.

Log in with Twilio as a Flex Admin
- Launching the Debugger with the correct Account SID - Sometimes you may run into some caching issues with chrome if you have multiple user accounts and/or tabs open, which can result in your debugger being tied to the wrong account. Closing all chrome instances should resolve the problem or clearing the cache may help, and worst case a reboot of your machine will give you a clean slate. - Attaching the Debugger instead of Launching it from VS Code - In this blog post we’ve shown you how to debug in VS Code using the “Launch” option, but you may be more comfortable using the “Attach” option. Both options are viable. If you want to use “Attach” check out the VS Code Launch vs. Attach Configuration doc. - Limitations when working with breakpoints in Twilio Functions - While your debugging instance will allow you to pause at any given breakpoint for as long as you want before continuing execution, Twilio does enforce timeouts on TCP connections to your URL. We will issue an 11205 - HTTP Connection Failure if a response is not received in 15 seconds. This doesn’t diminish the value of debugging, and you can certainly continue with a debugging thread (including context) even after the connection with Twilio is broken. To test a running process from end-to-end, you eventually are going to have to run through the debugging process while being mindful to avoid this limitation. - You can use request replaying either through the Twilio Debugger or through the ngrok inspector if you need to test the same request again. - Version management on deployed Plugins and Functions (using the Twilio CLI) - New Versions 1. Consult the `Deploy` and `Promote` commands as part of the Serverless Plugin, or head over to our docs page to learn more. - Rollbacks - The process to rollback a deploy is as follows 1. Get the Build SID you want to roll back to 2. Create a new deployment for it (with the CLI you can use `twilio serverless:promote`) 3. Once the old build SID is active, delete the new build 4. Optionally delete the function/asset versions referenced in the old build

twilio serverless:list environments will give you the currently active build sid for each environment, and twilio serverless:list builds will list all builds for the service.

- Monitor your hosted functions in the Twilio Console - In the Twilio Console Functions API page, click into the “Show Logs” under the Functions environment. Click on the appropriate function you wish to monitor. Note: Alternatively, if you are using version 1.6.0 or greater of the Serverless Plugin, you can use the CLI command `twilio serverless:logs` and/or `twilio serverless:logs --tail` - When the function is executed, all of your console.log() statements will log in real time in the embedded window.

Show Flex Logs on your domain

Additional Resources

These resources are complementary to this blog in that they may give you a different spin on ways to accomplish some of what is covered in this blog, and possibly expand on certain elements that were not covered here.

What’s Next From Twilio?

We recognize that the build/deploy process could be even more streamlined than it is now (e.g., a single command to deploy your Plugin + Functions), and we are hard at working on making improvements to our Flex Plugin Builder as we speak.

Subscribe to our Changelog on Twitter to make sure you’re receiving the latest updates from Twilio, as this is a great way to stay informed as we make improvements to Plugin Builder and many other features across the Twilio Platform.

Chris Feehan is a Principal Solutions Engineer at Twilio. Chris has a history of architecting and building custom solutions and integrations for customers in both the public and private sectors. At Twilio, Chris has worked to enable customers spanning Growth and Enterprise segments, building numerous reusable solutions with Twilio products like Proxy, Autopilot, and Conversations. Chris leads a select group of SE’s working with Product and Marketing teams on customer engagement opportunities across Twilio’s messaging platform. Chris can be reached at cfeehan [at]

Want to see Twilio Flex in action? Check out our interactive demo.

Ready to start building your contact center? We're offering $5,000 worth of free Flex Hours to help you get started. Sign up and start building with Twilio Flex!