---
name: azion-deploy-a-function-with-azion-cli
description: >-
  Create a function project from the terminal with Azion CLI, run it on your machine, and deploy it to a live domain.
---

# Deploy a function with Azion CLI

In this tutorial, you will build and deploy a function from the terminal with [Azion CLI](/en/documentation/devtools/cli/). You will save a personal token and create a project. Then you will write the handler, run it on your machine, and deploy it.

The [Functions quickstart](/en/documentation/platform/functions/quickstart/) reaches the same result through Azion Console. This page is the terminal path, and it ends with the same three objects: a function, an instance, and the application that serves it.

## Prerequisites

- An Azion account. To create one, refer to [Create an account](/en/documentation/fundamentals/creating-account/).
- [Azion CLI](/en/documentation/devtools/cli/) installed on your machine.
- A [personal token](/en/documentation/fundamentals/personal-tokens/).
- Node.js and a package manager, which the CLI uses to build the project.

## 1. Save your personal token

The CLI authorizes every command with a personal token stored on your machine. To save it:

```bash
azion -t <your-token>
```

The token is stored locally, and the commands that follow authorize with it. You do not pass it again.

## 2. Create the project

[`azion init`](/en/documentation/devtools/cli/init/) creates the project and its build configuration. To start it:

```bash
azion init
```

The command asks for a name, suggesting one you can accept:

```bash
? Your application's name:  (affectionate-chaos)
```

Then it asks which preset to use. Select **Javascript**, the preset for a function written in plain JavaScript rather than a framework:

```bash
? Choose a preset:  [Use arrows to move, type to filter]
> AI Studio
  Angular
  Astro
  ...
  Javascript
```

Then it asks which template to start from. Select *Hello World*:

```bash
? Choose a template:  [Use arrows to move, type to filter]
> Hello World
  HTMX Boilerplate
  Simple Javascript Router Node
  Simple Javascript Router
  QStash EdgeFunction Scheduler
  Upstash Geolocation
  Upstash Rate Limit
```

It asks whether to install the project dependencies. Answer `Y`:

```bash
🤔 Do you want to install project dependencies? This may be required to generate initial configuration file (Y/n)
```

It asks whether to start a local development server. Answer `N`, because step 4 starts it:

```bash
🤔 Do you want to start a local development server? (y/N)
```

The project directory now holds the build configuration and the entrypoint the build reads.

## 3. Write the handler

Open `index.js`, the entrypoint the build reads by default, and replace its contents with an ES Modules handler:

```js
export default {
  async fetch(request, env, ctx) {
    return new Response('Hello World', {
      headers: { 'content-type': 'text/plain' }
    });
  }
};
```

The `fetch` method receives the request, the environment variables, and the execution context, and returns the response the client receives. This is the pattern Azion recommends.

## 4. Run the function locally

Before deploying, run the project on your machine and send it a request. To start the local server with [`azion dev`](/en/documentation/devtools/cli/dev-command/):

```bash
azion dev
```

The command builds the project, then prints the address it serves on:

```bash
[Azion] [Server] › ✔  success   Function running on port 0.0.0.0:3333, url: http://localhost:3333
```

From another terminal, request that address:

```bash
curl http://localhost:3333/
```

The handler answers with its response body:

```bash
Hello World
```

Stop the server with `Ctrl+C` once the response is correct.

## 5. Deploy the project

To deploy the project to Azion with [`azion deploy`](/en/documentation/devtools/cli/deploy/):

```bash
azion deploy
```

The command builds the project and creates the application and the function on your account. It instantiates the function and prints the domain that serves it. The domain has the format `xxxxxxxxxx.map.azionedge.net`.

Requesting that domain returns the same response you read locally:

```bash
curl https://xxxxxxxxxx.map.azionedge.net/
```

```bash
Hello World
```

The first deploy can take several minutes to answer from every location. An immediate request can fail before the configuration is in place. Wait and retry before diagnosing.

## Next steps

- [Develop and test a function locally](/en/documentation/platform/functions/local-development.md): Run the project on your machine and supply environment variables from a local file.
- [How Functions works](/en/documentation/platform/functions/how-it-works.md): What has to exist before a function runs on a request.
- [JavaScript examples](/en/documentation/platform/functions/javascript-examples.md): Handlers to copy into the project as a starting point.
- [Azion CLI](/en/documentation/devtools/cli.md): Every command the CLI accepts, and the flags for each one.
