Dart Aqueduct server for your Flutter app — Part 1: Getting started

Feb 6 · 8 min read

Introduction to Server Side Dart with Aqueduct

If you’re already a backend developer, you can quit reading. Your current skills will work just fine for your Flutter app.

If you aren’t interested in Flutter, you can also quit reading. You might as well learn a more popular backend server framework like Node.js or something.

And if your serverless Firebase setup is working well for you, then don’t let me discourage you.


Ok, is everyone else gone now? It’s just you and me, reader. I was like you not long ago. I knew Flutter, but I didn’t have any experience building a backend server. Well, let me tell you, you’re going to love Server Side Dart. Being able to code in the same language in your frontend Flutter app and in your backend server makes the learning curve very, very small. Jumping between the two is hardly any different that opening two different files in the same project.

The language we’ll be using to build the server is Dart, but if you’re interested in knowing why I chose the Aqueduct framework, you can read my previous article in the link below.

Originally I was going to publish this as a paid course on Udemy. I got partway through making all the videos, but it was taking too long and I needed to move on to other projects. The videos were just sitting there doing nothing, so I decided to upload them to YouTube. I’ll intersperse them in these written lessons to supplement what I write. You’re free to completely skip these written tutorials, but the advantage here is that it will be easier to copy and paste the code snippets as you go. Also, it’ll be easier for me to update any errors in the written content.

Here is the first video if you prefer listening to reading:

Content preview

In this series of posts I’ll be guiding you through how to set up a secure server as a backend for your Flutter app. (If I tell you to do anything that isn’t secure, then leave a comment to warn others and to educate me.)

I’ll break the lessons into seven parts:

Through all of these lessons we’ll be making a dictionary app. Partly (OK, mostly) that’s because this is something I actually want to do some time. But it also provides a good example of many functions you’ll want in your own server app. You can just change the details to fit your requirements. (I’ve even been watching my own videos recently to relearn the concepts as I’m make a backend for another project.)

Now you’re going to install Dart and get the IDE set up. If anything isn’t clear from the written text, you can watch how to do that here:

Install Dart

Install the Dart SDK by going to the official Dart site. There you’ll find specific directions for installing it on Mac, Linux, and Windows.

You might be thinking you can just use the version of Dart that is included with Flutter. That may be true, but I’ve heard there are slight differences, so I recommend you just install the standalone Dart SDK. That’s what you’re going to be running on the server later anyway.

Check that you have Dart installed by running the following command in the terminal:

dart --version

At the time of this writing my Dart version is 2.7.1.

If your system didn’t recognize the Dart command, check that it is in your PATH. For example, on Mac and Linux you can do that on the command line as follows:

echo $PATH

If dart isn’t in the path, then you’ll need to add it.

IDE setup

I’m using IntelliJ Idea throughout this series, but VS Code works just fine, too. If you’re an Android Studio user, you’ll feel right at home in IntelliJ since that is what Android Studio is based on.

Install IntelliJ from the official site here. Downloading the free Community version is just fine for Dart development.

Install the Dart plugin

Open IntelliJ and on the startup window choose Configure > Plugins > Marketplace and search for Dart. Then install that plugin. If you already have an IntelliJ project open you can go to Preferences > Plugins to do the same thing. (If you are using VS Code click the Extensions button on the sidebar and search for Dart).

We’re not going to create a new project here in IntelliJ. We’ll use Aqueduct to do that in just a minute.

Install Aqueduct

Now that Dart is installed, we’ll install Aqueduct, which is a framework written in Dart to greatly simplify the process of making a backend server.

Go to the official Getting Started with Aqueduct page for directions and documentation. You’ll want to bookmark this site because there are loads of good documentation to help when you get stuck.

To install Aqueduct, type the following command in the terminal:

pub global activate aqueduct

You’ll probably get a message that tells you to add Aqueduct to your path. Once you do that and restart your terminal, you should be able to run Aqueduct commands on the command line.

Type the following:

aqueduct --version

At the time of this writing, I’m using Aqueduct version 3.2.1. Again, if aqueduct is not recognized by your shell, you need to add it to the path and restart your terminal.

Create a new project

In the terminal, cd to whatever location you would like to create your project.

In the original version of this article I recommended structuring your server and client side files like in the following outline and using a single GitHub repo. You can can still use this file structure, but now I recommend that you use two different repos for the client and server. When you deploy the server it is easier to use git clone if the server has its own repository.

(Aqueduct files here)
(Flutter files here)

For this series I’ll call the Aqueduct project dart_server. Create it like this:

aqueduct create dart_server

In IntelliJ (or VS Code), open the dart_server folder. If you get a message about enabling Dart for your project, do that.

REST APIs and HTTP methods

The server you just created is an HTTP server. You will be using it to make a REST API to communicate back and forth with your Flutter app. If any of those terms are unfamiliar to you, read the following article that I wrote as a supplement to this series:

Run the server

At this point you’ve already created an Aqueduct server. Before you finish this unit, though, you’re going to take the server on a test run.

In your IDE, open the pubspec.yaml file at the root of the dart_server project. With the file structure being so similar to Flutter, this already feels quite familiar, doesn’t it?

good ol’ pubspec.yaml

Change the description to the following:

description: Aqueduct dictionary application

And change the author to your own name and email:

author: Suragch <me@example.com>

In the terminal, start your Aqueduct server by running the following command in the root folder of your project:

aqueduct serve

You should see the following output in the terminal:

-- Aqueduct CLI Version: 3.2.1
-- Aqueduct project version: 3.2.1
-- Preparing...
-- Starting application 'dart_server/dart_server'
Channel: DartServerChannel
Config: /Users/.../dart_server/config.yaml
Port: 8888
[INFO] aqueduct: Server aqueduct/1 started.
[INFO] aqueduct: Server aqueduct/2 started.

Your server is now running!


  • The port is 8888. This is the default port for Aqueduct.
  • The aqueduct/1 and aqueduct/2 are two different instances of the server. They are running on two different Dart isolates, so they don’t talk to each other. Having two of them running at once allows you to handle more simultaneous connections and make better use of multi-core CPU hardware.

You can stop the server by pressing Ctrl+C, but don’t do that yet. You’re going to test the server by making a GET request.

Test the server

Open any browser and in the address bar enter the following address:


You use localhost because the server is running on your own machine, and as I mentioned above, 8888 is the port that Aqueduct is using to communicate on.

After entering that address, you’ll get a 404 Not Found error:

http://localhost:8888/ not found

Actually, this is good because it means the server is working. Aqueduct is the one that produced that error message. All it means is that you haven’t defined any route for localhost:8888/.

In your IDE, open lib/channel.dart.


Near the bottom of the file you should find a router object.

.linkFunction((request) async {
return Response.ok({"key": "value"});

Ah, you can see that the defined route is /example. Let’s try that in the browser:


It worked! The server returned a JSON key-value pair for the route /example. When browsers visit an address, they’re making a GET request behind the scenes. In the next section you’ll not only make and handle more GET requests but also POST, PUT, and DELETE.

After I’ve finished that article, I’ll add a link here. Until then feel free to continue watching the video series or follow the Aqueduct documentation.

Flutter Community

Articles and Stories from the Flutter Community


Written by


A Flutter and Dart developer with a background in Android and iOS. Follow me on Twitter @suragch1 or become a Patron: www.patreon.com/user?u=32145209.

Flutter Community

Articles and Stories from the Flutter Community

More From Medium

More from Flutter Community

More from Flutter Community

More from Flutter Community

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade