# General Usage

> \[!NOTE]
>
> This means this project is 100% open-source. You can find its source code in the [Twilio Labs GitHub organization](https://github.com/twilio-labs).
>
> We currently don't support the projects through our official support channels. But you are welcome to reach out to us on GitHub for any questions, issues or suggestions or to contribute to this project.
>
> [Learn more about Twilio Labs](/docs/labs).

There are two ways you can use the [toolkit](/docs/labs/serverless-toolkit). If you are already using the Twilio CLI, you can install it via a plugin. Alternatively, you can use the toolkit as a standalone using twilio-run via npm or another Node.js package manager.

Throughout the docs we'll reference the Twilio CLI commands.

## Create a Project

There's a variety of ways you can get started with a Twilio Serverless project. If you are intending to use the Twilio Serverless Toolkit, you'll have to have a project that adheres to a certain structure (more below). The toolkit actually supports scaffolding projects to get some example Functions and the right folder structure.

```bash title="Create Twilio Serverless project"
# Initialize a new project with the name my-project
twilio serverless:init my-project

# Change into that new project directory
cd my-project
```

## Project Structure

By default the Twilio Serverless Toolkit uses the filesystem structure of your project to make conclusions of what to do. If you use the Toolkit to create your project, you'll already have a valid structure like this:

```bash
my-project
├── .env
├── .gitignore
├── .nvmrc
├── .twilioserverlessrc
├── .twiliodeployinfo
├── assets
│   ├── index.html
│   ├── message.private.js
│   └── style.css
├── functions
│   ├── hello-world.js
│   ├── private-message.js
│   └── sms
│       └── reply.protected.js
├── package-lock.json
└── package.json
```

### Configuration and Meta Files

By default the Twilio Serverless Toolkit uses conventions over configuration. However we do provide some configuration options and store some meta information in your project in the shape of `.twilioserverlessrc` and `.twiliodeployinfo` files. You can [learn more about them in the Configurations section](/docs/labs/serverless-toolkit/configuration).

### Project Dependencies

Anything that will be found in the `dependencies` field of your `package.json` in your project directory will be available both for local development as well as installed in your deployed project.

You can add new dependencies by using any Node.js package manager that writes to the `package.json` like `npm` to install dependencies.

> \[!WARNING]
>
> Dependencies that are installed locally but are not under `dependencies`, like anything installed as `devDependencies`, might be available during local development but will not be available during deployment. The `deploy` command will list all dependencies that are being installed upon deployment.

### Environment Variables

We use `.env` files for all environment variables. By default we will **not** make any other environment variables on your system available for your local development. We'll use the same file to determine the values that should be uploaded for deployment. You can change the location of your `.env` file using the `--env` flag (for example: `--env=./.env.staging`) or by using the [configuration file](/docs/labs/serverless-toolkit/configuration).

Learn more about .env files:

* [Structure of a .env file](https://github.com/bkeepers/dotenv#usage)
* [A small tutorial on how to use .env files in general](https://github.com/Techtonica/curriculum/blob/master/command-line/env.md)

There are a few variables that behave differently. Namely:

* `DOMAIN_NAME` and `PATH`. These are automatically set both during local development and in your deployed environment unless they are overridden by a value in your `.env` file.
* `ACCOUNT_SID` and `AUTH_TOKEN`. During local development these are set through your .env file. During deployment they'll be replaced with the relevant account information you deployed to.
* `SERVICE_SID` and `ENVIRONMENT_SID`. During local development these will be `undefined` by default and will log a warning starting with `@twilio/runtime-handler` version `1.1.2`. In your deployed version these will be populated with the relevant information for your deployment unless you overrode the values using the `.env` file with your own custom values.

#### How to use SERVICE\_SID and ENVIRONMENT\_SID in local development

The most common use case for using `SERVICE_SID` and `ENVIRONMENT_SID` is to retrieve or manipulate things related to a deployment. For example permanently updating an environment variable by calling the Serverless API directly.

Since your local development environment only imitates the Twilio Functions Runtime there is no actual Service and therefore no Service SID and Environment SID that we can provide. Instead these values will be `undefined`. You will, however, see a warning emitted into your local development logs when accessing this undefined value to warn you that during deployment these will automatically be populated. You can use this information to gate behavior to only happen in your deployed instance. By writing code similar to this:

```javascript
exports.handler = function(context, event, callback) {
  if (context.SERVICE_SID) {
     callback(null, 'Ahoy from the Twilio Cloud!');
  } else {
     callback(null, 'Hello from my local environment');
  }
}
```

### Functions

All Functions have to be under a common root directory. By default this will be `functions/` but you can alternatively use `src/`. If neither of them works, there's a flag `--functions-folder` or `functionsFolder` config option that you can use to specify a different directory as the root directory for your Functions.

Anything under that root directory will be uploaded as a Twilio Function. The path for each function is relative to the root directory with the `.js` strapped away.

For example a `functions/` directory like this:

```bash
my-project
├── functions
│   ├── example.js
│   └── sms
│       └── reply.js
```

Would result in two Functions being created at the paths `/example` and `/sms/reply`.

If you would deploy these files both of these Functions would be publicly accessible. If you want to lock them down to only be accessible by Twilio, for example to use them as a webhook, you can mark a Function as *protected*. This can be done renaming your file to have an extension of `.protected.js`.

**Note:** This will not influence the path of the Function. Meaning a file `functions/example.js` and `functions/example.protected.js` will both result in a path of `/example` but the second one will make sure to enforce a [valid Twilio request signature](/docs/usage/security#validating-requests).

### Assets

Creating Assets works similar to creating Functions. By default the toolkit will look for an `assets/` or alternatively `static/` folder. With the `--assets-folder` flag or `assetsFolder` config option you can change this directory to any other root directory.

However, Assets will preserve their extensions for the path. So for example a file under `assets/index.html` would result in a path of `/index.html`.

Assets are a great way for you to also host resources that you want to access from your Functions that are not other Functions or should not be available to the public. For example configuration files or other JavaScript files you want to `require()`. You can store those as *private Assets.*

To mark an Asset as private, include `.private.` in the filename. This will create a private Asset but the `.private.` annotation will be removed during upload. In order to accessing a private asset you'll have to use the global `Runtime.getAssets()` function. You can learn more about it in the [Runtime documentation](/docs/serverless/functions-assets/client).

## Start developing locally

The Twilio Serverless Toolkit allows you to develop locally to test out your Functions and Assets before deploying them to Twilio. It also allows you to attach a debugger to debug your Function logic or even spin up an *ngrok* tunnel to test your Functions directly with Twilio.

There's a variety of options that you can use when kicking off the local development command but the quick way to get started is to run it without any arguments.

```bash title="Run a Serverless project locally"
# Start the local development environment with live reloading of Functions
twilio serverless:start
```

## Create a new Twilio Function

Since any JavaScript file inside your functions directory of your project will turn into a Function, creating a new Twilio Function can be as quick as creating a new file with this content:

```javascript
exports.handler = function(context, event, callback) {
  const twiml = new Twilio.twiml.VoiceResponse();
  twiml.say("Hello World!");
  callback(null, twiml);
};
```

If you want to learn more about the different variables passed into this Function during the execution or other things that will be available during the execution, make sure to check out the documentation of the [Twilio Function Runtime](/docs/serverless/functions-assets/functions/invocation).

To make creating a new Twilio Function more convenient and get you started quicker, we added another command that lets you create a new Function and pick from a collection of existing templates.

```bash title="Create a new Twilio Serverless Function"
# Creates a new function with the path and name /my-new-function
twilio serverless:new my-new-function
```

These templates are dynamically loaded from our [Function Templates repository on GitHub](https://github.com/twilio-labs/function-templates) and we always welcome new contributions.

If you want to see a list of available templates with a short description directly in you terminal, you can use the `serverless:list-templates` command to list all templates.

```bash title="List available Function templates"
# List all available Function templates
twilio serverless:list-templates
```

## Deploy a project

Once you have your project setup, you are just one command away from deploying your Twilio Serverless project. The *deploy* command will set some defaults based on your filesystem:

* The toolkit will create a Twilio Serverless service for you. By default it will read the `name` entry in your `package.json`. You can use the `--service-name` flag to override this name
* Twilio Serverless introduces the concept of [Environments](/docs/serverless/api/resource/environment). By default the toolkit will deploy to an environment with the domain suffix *dev* and the name *dev-environment*. This can be changed through the `--environment` flag.
* The toolkit will upload all variables set in your `.env` file for your deployment. You can change it to use a different `.env` file using the `--env` flag.
* Any dependency that is listed in the `dependencies` field in your `package.json` will automatically be installed in your deployment.

```bash title="Deploy a Twilio Serverless project"
# Run a basic deployment with default settings
twilio serverless:deploy
```

## What's next?

Now that you were able to deploy your first Twilio Serverless project, it's time to learn more about some of the other options that you have.

* [Getting Started](/docs/labs/serverless-toolkit/getting-started)
  * [Install the toolkit](/docs/labs/serverless-toolkit/getting-started#install-the-twilio-serverless-toolkit)
  * [Explore available commands](/docs/labs/serverless-toolkit/getting-started#explore-the-commands-and-options)
* [Examples](/docs/labs/serverless-toolkit/examples)
