Running a Flutter web app and API on Node.js
Tags: node, flutter, javascript, webdev
Published: 2019-10-23 19:50:22

---
title: Running a Flutter web app and API on Node.js
published: true
date: 2019-10-23 18:00:03 UTC
tags: node,flutter,javascript,webdev
canonical_url: https://blog.logrocket.com/flutter-web-app-node-js/
cover_image: https://thepracticaldev.s3.amazonaws.com/i/ume223r2l2471rlc87db.jpeg
---
**Written by [Brian De Sousa](https://blog.logrocket.com/author/briandesousa/)**✏️

There are a plethora of cross-platform app development frameworks that allow you to code an app once and run it on multiple platforms like Android, iOS, and even on a desktop. You may have heard of popular frameworks like Ionic, [Xamarin, and React Native](https://dev.to/bnevilleoneill/flutter-vs-react-native-vs-xamarin-29c2). Another framework that is relatively new on the scene is Flutter.

In this article, you will learn a bit about Flutter, with a particular focus on web support, which recently became [available as a technical preview](https://flutter.dev/web) in version 1.9. You will add web support to an existing Flutter app and run it on a Node.js server alongside a simple API.

## Flutter at a glance

Flutter is one of Google’s solutions to cross-platform development. While it is fairly new on the scene, its feature set makes it an instant competitor in this space.

It compiles your app down to native code that runs on iOS or Android, resulting in incredible end-user performance and frame rates. It supports stateful hot reloading during development, meaning you can make changes to your code and watch them get applied on your emulator or physical device with no need to restart your app or lose your app state.

Flutter’s primary focus has been iOS and Android. With the 1.9 release, web support has been added as a technical preview. It is still in its early days, and it may not be production-ready just yet, but it is certainly exciting and promising. Minimal changes are required to take an existing Flutter app and compile it into an HTML, CSS, and JS bundle, as you will soon see.

[![LogRocket Free Trial Banner](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2017/03/f760c-1gpjapknnuyhu8esa3z0jga.png?resize=1200%2C280&ssl=1)](https://logrocket.com/signup/)

## Why run a Flutter web app on Node.js?

Flutter web apps can run on any web server. So why would you want to host your Flutter web app on a Node.js server? Well, to be honest, for many of the same reasons that you’d choose Node.js for your other web apps and APIs: it is incredibly good at servicing large volumes of simple requests, you can code your front end and back end in JavaScript, and so on.

You might already have a Node.js API that serves data to your Flutter iOS or Android apps. Compiling your Flutter app as a web app and hosting it on your existing Node.js server might be a logical extension to your current solution, with no need to add additional hosting costs to the equation.

## Demonstration

It’s time to dive into the code and see Flutter web in action. In order to follow along with the example, you will need the following tools:

- Android Studio (Android SDK manager and emulator)
- Visual Studio Code + Flutter extension (or Android Studio)
- Node.js 12

Flutter has fantastic developer documentation. If this is your first time developing a Flutter app, follow the “[Get started](https://flutter.dev/docs/get-started/install)” guide to get all your tools set up.

You will have the opportunity to choose which editor you want to develop in. The examples and instructions in this article are based on Visual Studio Code, but you should still be able to follow along if you choose to use Android Studio instead.

A Node.js 12 server is required to run the web version of the Flutter weather app as well as the back-end weather API.

### Step 1: Explore the sample code

In order to demonstrate how to add web support to an existing Flutter app, we will start with a simple weather app that has been tested on Android 10 (API level 29).

![Flutter Weather App On Mobile](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2019/10/flutter-weather-app-mobile.png?resize=301%2C608&ssl=1)

The weather app allows the user to view the current weather for a predefined list of cities. Weather data is retrieved from a back-end server running on Node.js.

Clone the source code for the weather app and server from GitHub:

- [briandesousa/weather\_app\_flutter](https://github.com/briandesousa/weather_app_flutter)
- [briandesousa/weather-app-nodejs-server](https://github.com/briandesousa/weather-app-nodejs-server)

> **Tip:** The `weather-app-nodejs-server` repository has a `flutter-web-support` branch that contains the completed version of the app copied to the server with Flutter web support enabled.

It is best to clone both repositories beside each other in the same parent folder. The contents of the `weather_app_flutter` repository will be built and copied to a folder within the `weather-app-nodejs-server` repository.

#### Explore the Flutter weather app

Open the `weather_app_flutter` repository in your editor. Let’s take a closer look at the `main.dart` file. It contains the scaffolding and widgets that make up the app’s user interface. The `Home` widget class has a `fetchWeatherData` function that calls the back-end weather API to retrieve data and update the widget’s state:

```jsx
fetchWeatherData({String location}) async {
    var url = WEATHER_API_URL + location;
    final response = await http.get(url);
    if (response.statusCode == 200) {
      var jsonResponse = convert.jsonDecode(response.body);
      setState(() {
        this._weatherData = WeatherData(
          jsonResponse\['weather'\]['location'],
          jsonResponse\['weather'\]['temperature'],
          jsonResponse\['weather'\]['weatherDescription'],
        );
        this._apiError = null;
      });
    } else {
      setState(() {
        this._apiError =
            'Unable to retrieve weather data from API (HTTP ${response.statusCode})';
      });
    }
  }
```

The `fetchWeatherData` function uses Dart’s `http` package to connect to the server over HTTP. There are other Dart packages that you could use, but this is the officially recommended package if you plan on adding web support to your Flutter app.

Also make note of the `WEATHER_API_URL` constant. Update the value of this constant before running the app so that it can connect to the API running on your local Node.js server. The URL must contain your machine’s hostname. A `localhost` URL will not be accessible to the Android emulator or physical device.

#### Explore the Node.js server and weather API

Open up the `weather-app-nodejs-server` repository in your editor.

![Node.js Server Repository In Our Code Editor](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2019/10/weather-app-nodejs-server.png?resize=203%2C336&ssl=1)

There are a few important files and folders to review:

- The `public/api-test.html` file can be used to quickly test that your server is working as expected after startup (e.g., `http://localhost:3000/api-test.html`)
- The `routes/weather.js` file contains a simple GET API that accepts a path parameter and returns weather data (e.g., `http://localhost:3000/api/weather/londonon`)
- The `public-flutter` folder is where you will copy the compiled web version of the weather app. The Node.js server is set up to serve files from this directory to the root context (e.g., `http://localhost:3000`)

### Step 2: Add web support to the Flutter app

Since web support is still a technical preview, you need the latest in-development version of Flutter, also referred to as the master channel. In the root folder of the `weather_app_flutter` repository, run the following commands:

```jsx
flutter channel master
flutter upgrade
```

> **Tip** : You may encounter an “Unknown operating system. Cannot install Dart SDK.” error on Windows when running Flutter commands in a bash shell in Visual Studio Code. Try running the commands in a normal Windows command shell.

The upgrade process may take a few minutes. Next, you will need to enable web support in your Flutter installation so that it is available to this and other apps you develop on this workstation:

```jsx
flutter config --enable-web
flutter devices
```

Once web support is enabled, you will see a new Chrome device in the device list. Restart Visual Studio Code after running these commands to refresh the device list menu if you don’t see Chrome in that list yet.

To add web support to the weather app, you need to run this command in the top-level folder of the `weather_flutter_app` repository:

```jsx
flutter create .
```

The `create` command will make a few modifications to the app, which you can see in [this commit](https://github.com/briandesousa/weather_app_flutter/commit/7639c7041614d99a945709be269a7d76b991912a). The most notable change is the addition of a `web` subfolder that contains an `index.html`:

![Index.html File In Our Code Editor](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2019/10/index.html-file.png?resize=730%2C201&ssl=1)

Start the Node.js server by running this command in the root of the `weather-app-nodejs-server` repository:

```jsx
npm start
```

Select Chrome from the device list in Visual Studio Code and then start the debugging. Alternatively, you can run the following flutter command:

```jsx
flutter run -d chrome
```

The first time you start the app in Chrome may take a little longer while Flutter downloads additional dependencies on the fly. Chrome will eventually open, and you will see the weather app running in the browser. Some of the styling will be slightly different than what you saw on the emulator or physical device.

![App Preview In Chrome](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2019/10/app-preview-chrome.png?resize=730%2C413&ssl=1)

At this point, you will notice that the app is not displaying any data from the weather API. If you open Chrome DevTools, you will see a [cross-origin resource sharing](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing) error.

The browser is not allowing the request to be made from the Flutter web server to the Node.js server since they are running on different ports. You could solve this problem by enabling cross-origin resource sharing on the server or installing a Chrome plugin to disable CORS.

We are going to ignore the error for now since in the next step we will run the pre-compiled Flutter web code directly on the Node.js server, thus eliminating the cross-origin requests altogether.

Try making a change to some of the code in the `main.dart` file and let Flutter recompile your app. You will notice that your changes do not immediately appear in the browser. This is because Flutter web does not yet support hot stateful reloading. Hopefully support for this awesome capability will come soon.

> **Tip:** A detailed explanation of each of the Flutter commands in this section is available on [flutter.dev](https://flutter.dev/docs/get-started/web).

### Step 3: Run the Flutter web app on Node.js

Now that you can run the weather app in the browser using Flutter, the next step is to build and copy it to the Node.js server to run alongside the API.

To build a Flutter web app bundle, run this command:

```jsx
flutter build web
```

The build command will produce the `build/web` folder containing all the static files that make up the weather app.

![Contents Of The build/web Folder In Our Editor](https://i1.wp.com/blog.logrocket.com/wp-content/uploads/2019/10/buildweb-folder.png?resize=212%2C426&ssl=1)

Copy the contents of `weather_app_flutter/build/web` to `weather-app-nodejs-server/public-flutter`. If your Node.js server in is still running, stop it and restart it to pick up the new files.

Access your Node.js server in the browser at `http://localhost:3000` to see your app running on Node.js. This time, your app will display weather data retrieved from the weather API without the cross-origin resource sharing error.

![Final App Running In The Browser](https://i1.wp.com/blog.logrocket.com/wp-content/uploads/2019/10/app-running-chrome.png?resize=730%2C528&ssl=1)

## Final thoughts

It is incredible how simple it was to take an existing Flutter app and compile it into a web app ready to be deployed to a web server. The user interface rendered in the browser looks nearly identical to the user interface in Android.

Tread lightly if you are considering Flutter as your cross-platform app framework solely because of its web support. The Flutter team is very clear that web support is missing features, has known performance issues, and is not quite ready for production yet.

One thing is for sure: the future of Flutter for web looks promising. You can read more about the Flutter web support and Project Hummingbird [here](https://medium.com/flutter/hummingbird-building-flutter-for-the-web-e687c2a023a8).
* * * 
**Editor's note:** Seeing something wrong with this post? You can find the correct version [here](https://blog.logrocket.com/flutter-web-app-node-js/).

## Plug: [LogRocket](https://logrocket.com/signup/), a DVR for web apps
 
![LogRocket Dashboard Free Trial Banner](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2017/03/1d0cd-1s_rmyo6nbrasp-xtvbaxfg.png?resize=1200%2C677&ssl=1)
 
[LogRocket](https://logrocket.com/signup/) is a frontend logging tool that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.
 
In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page apps.
 
[Try it for free](https://logrocket.com/signup/).
* * *
The post [Running a Flutter web app and API on Node.js](https://blog.logrocket.com/flutter-web-app-node-js/) appeared first on [LogRocket Blog](https://blog.logrocket.com).