# Create the App

> Install tinka and act, create the blog App from the skeleton starter kit, and run it with act serve, which rebuilds it on every save.

This chapter creates the App the rest of the tutorial builds on. You will learn how to:

- Install the Tinka CLI and `act`
- Create an App from the skeleton starter kit
- Run the App with `act serve` and send it a request
- Read what `act serve` does when you save a change

## Overview

The skeleton starter kit gives a new App the structure every later chapter relies on: configuration read from the environment, one place for routes, and tests ready to run. `act serve` then runs the App and builds it again each time you save a file, so you start it once, in a terminal of its own, and keep it running while you work.

## Install the tools

Tinka has two commands, both installed with Go's own tooling. `tinka` creates Apps, and `act` runs Commands inside an App, such as `act serve`.

::::steps

:::step{title="Install the Tinka CLI"}
```sh
go install github.com/mucolabs/tinka/cmd/tinka@latest
```
:::

:::step{title="Install act"}
```sh
go install github.com/mucolabs/tinka/cmd/act@latest
```
:::

::::

Go places both binaries in `$(go env GOPATH)/bin`, which must be on your `PATH`. [Installation](../installation.md) shows how to check them, and the setting Go needs during the alpha, while the Tinka repository is private.

## Create the App

Run `tinka new` with the directory to create. It asks which starter kit to use: choose `skeleton`. Answer yes when it asks whether to initialize a git repository, since the last chapter versions the App from its git tags.

```sh
tinka new blog
```

```text title="Output"
  Copying the skeleton kit ............................................ 5ms DONE
  Installing dependencies ............................................ 70ms DONE
  Initializing a git repository ....................................... 9ms DONE
Created blog with the skeleton kit

  cd blog
  act serve
```

`tinka new` copies the kit, requires the version of Tinka it was installed at, downloads the dependencies and generates the App's `APP_KEY` into `.env`. It also trusts the new directory, so `act` builds and runs the App's code without asking first. Move into the App:

```sh
cd blog
```

## Look around the App

The skeleton puts each kind of code in its own package. These are the ones the tutorial changes:

| Path | Holds |
|---|---|
| `main.go` | The entry point: it loads the configuration and runs the App |
| `start/app.go` | `App`, which builds the App and adds its services and Commands |
| `start/routes.go` | `Routes`, which registers the App's routes |
| `app/handlers` | The handlers that answer requests |
| `config` | The configuration, read from the environment at boot |
| `tests` | `tests.App`, which builds the App for tests, and the tests themselves |

[Folder structure](../folder-structure.md) describes every file. For now, two matter. `start/routes.go` registers the home route, and the health check routes the last chapter uses:

```go title="start/routes.go"
package start

import (
	"github.com/mucolabs/tinka"
	"github.com/mucolabs/tinka/health"

	"blog/app/handlers"
)

// Routes registers the App's routes. It runs as the App starts, after the
// providers registered their services, so it can resolve them; an error
// stops the App before it serves.
func Routes(app *tinka.App) error {
	app.Get("/", handlers.Home)

	// GET /health/live and GET /health/ready, for load balancers. Add a
	// check for each service the App can't serve without, such as its
	// database.
	app.Health(health.New(health.DiskSpace("/")))
	return nil
}
```

The home route's handler returns a struct, which the App sends as JSON:

```go title="app/handlers/home.go"
// Package handlers holds the App's handlers: the functions that answer
// requests.
package handlers

import "github.com/mucolabs/tinka"

type greeting struct {
	Hello string `json:"hello"`
}

// Home answers GET / with JSON.
func Home(c *tinka.Ctx) (greeting, error) {
	return greeting{Hello: "world"}, nil
}
```

## Run the App

Start the dev server from the App's directory, in a terminal you leave open:

```sh
act serve
```

```text title="Output"
  INFO  Watching for changes (inotify, 8 directories)
  INFO  Built in 1.3s, serving http://localhost:3000
[01:07:43.106] INFO: server started addr=127.0.0.1:35265 took=694.584µs
```

The lines starting with `INFO` come from `act serve`, and the timestamped ones from the App's own logger. `act serve` listens on `localhost:3000` and forwards each request to the App, which listens on a private port of its own: that's the address the App logs. In another terminal, request the home route:

```sh
curl localhost:3000/
```

```text title="Output"
{"hello":"world"}
```

The dev server's terminal logs the request, with its status, its duration and the request's ID:

```text title="Output"
[01:07:43.123] INFO: request method=GET path=/ status=200 took=83.306µs request_id=T2BGTXNW3JFUQLWPTFHY3S6PJW
```

## Save a change

`act serve` builds the App again each time you save a Go file, while the running App keeps answering. Make a mistake on purpose to see what a failed build does: remove `, nil` from the handler's `return`, and save.

```go title="app/handlers/home.go" del={3} ins={4}
// Home answers GET / with JSON.
func Home(c *tinka.Ctx) (greeting, error) {
	return greeting{Hello: "world"}, nil
	return greeting{Hello: "world"}
}
```

The build fails, and the dev server prints the compiler's error:

```text title="Output"
  ERROR  The build failed after 149ms; the App keeps running its previous code
# blog/app/handlers
app/handlers/home.go:13:9: not enough return values
	have (greeting)
	want (greeting, error)
```

`curl` still gets `{"hello":"world"}` from the App that was running before the change, so a typo never takes the App down. A page you open in the browser shows the error instead, where you're looking. Put `, nil` back and save again. The new build replaces the old App in a few milliseconds:

```text title="Output"
[01:08:03.974] INFO: server stopped
  INFO  Built in 965ms, restarted in 34ms
[01:08:04.015] INFO: server started addr=127.0.0.1:35265 took=805.55µs
```

Requests that arrive during the restart wait for the new App instead of failing. Keep `act serve` running: every change in the next chapters takes effect when you save it.

## Recap

You installed `tinka` and `act`, created the `blog` App from the skeleton starter kit, and ran it with `act serve`, which rebuilds and restarts it on every save and keeps the old App serving when a build fails. Next, [Routes and handlers](routes-and-handlers.md) gives the App its first posts.

See also: [Installation](../installation.md), [Folder structure](../folder-structure.md), [Development environment setup](../development.md), [Commands reference](../reference/commands.md#act-serve)
