# Upgrading - Vapor Docs

Skip to content


# Upgrading Versions

This document provides information about changes between version and tips for migrating your projects.

## 2.4 to 3.0

Vapor 3 has been rewritten from the ground up to be async and event-driven. This release contains the most changes of any previous release (and most likely any future release).

Because of this, it is recommended that to migrate your projects you start by creating a new, empty template and migrate by copy / pasting code over to the new project.

We recommend reading the Getting Started → Hello, world! section for Vapor 3 to familiarize yourself with the new APIs.

### Async

The biggest change in Vapor 3 is that the framework is now completely asynchronous. When you call methods that need to perform slow work like network requests or disk access instead of blocking they will now return a `Future<T>`.

Futures are values that may not exist yet, so you cannot interact with them directly. Instead, you must use `map`/`flatMap` to access the values.

    // vapor 2
    let res = try drop.client.get("http://vapor.codes")
    print(res.status) // HTTPStatus
    return res.status

    // vapor 3
    let f = try req.client().get("http://vapor.codes").map { res in
        print(res.http.status) // HTTPStatus
        return res.http.status
    }
    print(f) // Future<HTTPStatus>

See Async → Getting Started to learn more.

### Application & Services

`Droplet` has been renamed to `Application` and is now a service-container. In Vapor 2, the `Droplet` had stored properties for things you would need during development (like views, hashers, etc). In Vapor 3, this is all done via services.

While the `Application` is a service-container, you should not use it from your route closures. This is to prevent race conditions since Vapor runs on multiple threads (event loops). Instead, use the `Request` that is supplied to your route closure. This has a copy of all of the application's services for you to use.

    // vapor 2
    return try drop.view.make("myView")

    // vapor 3
    return try req.make(ViewRenderer.self).render("myView")
    // shorthand
    return try req.view().render("myView")

See Service → Getting Started to learn more.

### Database Connections

In Vapor 3, database connections are no longer statically accessible. This makes doing things like transactions and connection pooling much more predictable and performant.

In order to create a `QueryBuilder` in Fluent 3, you will need access to something `DatabaseConnectable`. Most often you can just use the incoming `Request`, but you can also create connections manually if you need.

    // vapor 2
    User.makeQuery().all()

    // vapor 3
    User.query(on: req).all()

See DatabaseKit → Getting Started to learn more.

### Work in progress

This migration guide is a work in progress. Please feel free to add any migration tips here by submitting a PR.

Join the #upgrading-to-3 in Vapor's team chat to ask questions and get help in real time.