Running a Rust Web Server

The first thing I want to do is get a web server running with Rust. I'm going to walk through installing Rust, creating a new project, using an Actix-Web server, and using Handlebar templates to render HTML.

Installing and Running Rust

First, the rustup toolchain manager needs to be installed. Rustup is to Rust as rvm/rbenv is to Ruby, nvm to Node, etc... Run the command below and it'll also install Rustup and the latest stable version of Rust.

$ curl --proto '=https' --tlsv1.2 -sSf | sh

Afterwards, you should be able to check the installed version of Rust and Cargo. Cargo is the package manager; think of it like npm, gem, etc...

$ rustc --version
rustc 1.39.0 (4560ea788 2019-11-04)
$ cargo --version
cargo 1.39.0 (1c6ec66d5 2019-09-30)

Creating your First Rust Program

Create a new directory for your project. In this case, create a directory called "running-a-rust-web-server". Change into the newly created directory and run cargo init. This will create the basic files needed for a Rust app. Plenty of resources exist that go into detail about what initially gets created, so I wont do that here. Next, run the application with cargo run and view it's output.

$ mkdir running-a-rust-web-server
$ cd running-a-rust-web-server
$ cargo init
Created binary (application) package
$ cargo run
Hello, world!

Creating a Web Server

Rust has a few different web frameworks to choose from which can be viewed here. I've chosen to use Actix-Web. Open the Cargo.toml file and add Actix-Web. It should look similar to the file below

name = "running-a-rust-web-server"
version = "0.1.0"
authors = ["Logan Keenan"]
edition = "2018"

# See more keys and their definitions at

actix-web = "1.0.9"

You can install your projects dependencies with cargo fetch. Cargo will also install dependencies when you build (cargo build). Note for javascript devs, dependencies are not download at a project level. They are downloaded once per version of Rust. Once dependencies have been fetched then the Cargo.lock file is updated automatically.

Actix-Web has made it super easy to get started. Their home page has some great sample code which we'll use too. Copy the code below to your src/ file and start your Rust web server (cargo run). You should be able to visit http://localhost:8000 and see Hello World.

use actix_web::{web, App, HttpRequest, HttpServer, Responder};

fn greet(req: HttpRequest) -> impl Responder {
    let name = req.match_info().get("name").unwrap_or("World");
    format!("Hello {}!", &name)

fn main() {
    HttpServer::new(|| {
            .route("/", web::get().to(greet))
            .route("/{name}", web::get().to(greet))
    .expect("Can not bind to port 8000")

Rendering HTML with Handlebar templates

I decided to go with Handlebars because it's a really simple templating language. We'll create a layout page which all other pages can use and then an index page which will be served at the root (http://localhost:8000).


{{#> layout_page}}
{{#*inline "page_content"}}

<!DOCTYPE html>
<html lang="en">
    <meta charset="UTF-8">
    <title>Rust Web Server Example</title>
        {{> page_content}}

Next we need to update our src/ file. The root route is going to register the directory containing the Handlebar templates and then pass data to the index template to render. The src/ file should look like the code below. Now you should be able to start the server (cargo run) and view the rendered html!

use actix_web::{web, App, HttpRequest, HttpServer, HttpResponse};
use handlebars::Handlebars;
use std::collections::BTreeMap;

fn root(_req: HttpRequest) -> HttpResponse {
    let mut handlebars = Handlebars::new();
        .register_templates_directory(".hbs", "./src/templates")

    let mut data = BTreeMap::new();
    data.insert("paragraph_text", "This page was rendered using Actix-Web as the web server and handlebars as the templating language!");

    let body = handlebars.render("index", &data).unwrap();


fn main() {
    HttpServer::new(|| {
            .route("/", web::get().to(root))
        .expect("Can not bind to port 8000")

Source Code