# Deploying Dart 2 apps on Heroku

Having spent the last 2 weeks working on a web app as part of exploring client-side development in Dart, I’ve got it [deployed on Heroku](https://memorygameweb.herokuapp.com/) and I want to show how you could do the same. I won’t be covering how I wrote the app since the focus here is on deployment. See the link to the source code at the end of the article.

## **Prerequisites**

You’ll need these to begin:

1. [Dart 2](https://www.dartlang.org/tools/sdk#install) [SDK](https://git-scm.com/downloads)
    
2. [Git](https://git-scm.com/downloads)
    
3. [Her](https://www.dartlang.org/tools/sdk#install)[oku](https://git-scm.com/downloads) [Acc](https://www.dartlang.org/tools/sdk#install)[ount](https://devcenter.heroku.com/articles/heroku-cli)
    
4. [Heroku CL](https://signup.heroku.com/)[I](https://devcenter.heroku.com/articles/heroku-cli)
    

Once they’re set up, login with your credentials by running `heroku login` in your terminal.

## **1\. Set up your web project**

Navigate to your project in the terminal. If you do not have one you could [clone my repo](https://github.com/graphicbeacon/dart_web_project) containing my solution and skip straight to step #3.

Alternatively, you could generate a test project using the **stagehand** scaffolding tool:

```bash
$ pub global activate stagehand
$ mkdir web_project && cd web_project
$ stagehand web-simple
```

## **2\. Write an HTTP server**

Amend the dependencies of the generated `pubspec.yaml` file to this:

```yaml
dependencies:
  shelf: any
  shelf_static: any
```

Run `pub get` to update our dependencies. We’re using **shelf** to simplify creating a web server.

Create `bin/main.dart` with the logic for spawning our server:

```dart
import 'dart:io' show Platform;
import 'dart:async' show runZoned;
import 'package:path/path.dart' show join, dirname;
import 'package:shelf/shelf_io.dart' as io;
import 'package:shelf_static/shelf_static.dart';

void main() {
  // Assumes the server lives in bin/ and that `webdev build` ran
  var pathToBuild = join(dirname(
    Platform.script.toFilePath()), 
    '..', 'build',
  );

  var handler = createStaticHandler(
    pathToBuild, 
    defaultDocument: 'index.html',
  );

  var portEnv = Platform.environment['PORT'];
  var port = portEnv == null ? 9999 : int.parse(portEnv);

  runZoned(() {
    io.serve(handler, '0.0.0.0', port);
    print("Serving $pathToBuild on port $port");
  }, onError: (e, stackTrace) => print('Oh noes! $e $stackTrace'));
}
```

## **3\. Run the project locally**

Install the **webdev** tool:

```bash
$ pub global activate webdev
```

Then run the command below to generate our bundle:

```bash
$ webdev build # or `pub global run webdev build`
```

This will produce a `build` folder.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1725633305088/356fb7d6-2fc2-4646-bde0-2ee31a937298.png align="center")

Run `dart bin/main.dart` and visit [`http://localhost:9999`](http://localhost:9999)

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1725633339861/fbd3671f-d993-47b5-82d1-47f51a8d0cc2.png align="center")

## **4\. Create your Heroku app**

Run the following command to create a new app:

```bash
$ heroku create
# Creating secure-spire-84236... done, stack is cedar-14
# http://secure-spire-84236.herokuapp.com/ | https://git.heroku.com/secure-spire-84236.git
# Git remote heroku added
```

This will generate a random name for your app, so `secure-spire-84236` in this case.

Lastly, commit your project and add `heroku` remote:

```bash
$ git init
$ git add .
$ git commit -m "Initial commit."
$ heroku git:remote -a secure-spire-84236
```

## **5\. Configure the buildpack**

Running the deploy command(`git push heroku master`) will throw an exception since Heroku requires the correct *buildpack* for running Dart apps.

A buildpack contains scripts that set the necessary dependencies to build and serve your project. Heroku does not officially support Dart at this present time.

However the platform allows us to specify custom buildpacks, and although the Dart team [has one](https://dev.to/graphicbeacon/deploying-dart-apps-to-heroku-23ih/edit), I made a [tweak](https://github.com/graphicbeacon/heroku-buildpack-dart/blob/ae89937a28eeb463d25299d5b37341dd138f4793/bin/compile#L103-L107) to get it working with Dart 2, so we’ll use my buildpack:

```bash
$ heroku buildpacks:set https://github.com/graphicbeacon/heroku-buildpack-dart.git
```

And set the required configurations needed by the buildpack:

```bash
$ heroku config:set DART_SDK_URL="https://storage.googleapis.com/dart-archive/channels/dev/release/2.0.0-dev.67.0/sdk/dartsdk-linux-x64-release.zip" # From the dart install page
$ heroku config:set DART_BUILD_CMD="/app/dart-sdk/bin/pub global activate webdev && /app/dart-sdk/bin/pub global run webdev build"
```

The tells the buildpack to pull the latest Dart SDK and build the project using the **webdev** tool.

## **6\. Deploy all the things!**

Create a `Procfile` at our project root with the instructions to start our server:

```yaml
web: ./dart-sdk/bin/dart bin/main.dart
```

Commit that change and now deploy:

```bash
$ git push heroku master
```

You should see a confirmation message with the web url:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1725633593325/68dd5775-d908-4aff-800e-eeb00e5700b4.png align="center")

And visit in the browser:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1725633612701/069988e4-386f-4ab1-a276-e916eb66f779.png align="center")

Here’s the [game](https://memorygameweb.herokuapp.com/) I deployed and the [source code](https://github.com/graphicbeacon/memory-game-web).

**Like, share and follow me** for more content on Dart.

## **Quick links**

1. [Dart 2 SDK](https://www.dartlang.org/tools/sdk#install)
    
2. [How Heroku Works](https://devcenter.heroku.com/articles/how-heroku-works)
    
3. [Get Started | Webdev Dart](https://webdev.dartlang.org/guides/get-started)
    
4. [**Free Dart screencasts on Egghead.io**](http://egghead.io/instructors/jermaine-oppong)
