---
title: Applications
description: Learn how to leverage applications to structure your projects.
sidebar_label: Applications
---

Marten projects can be organized into logical and reusable components called "applications". These applications can contribute specific behaviors and abstractions to a project, including [models](../models-and-databases.mdx), [handlers](../handlers-and-http.mdx), [schemas](../schemas/introduction.md), [emails](../emailing/introduction.md), and [templates](../templates.mdx). They can be packaged and reused across various projects as well.

## Overview

A Marten **application** is a set of abstractions (defined under a dedicated and unique folder) that provides some set of features. These abstractions can correspond to [models](../models-and-databases.mdx), [handlers](../handlers-and-http.mdx), [templates](../templates.mdx), [schemas](../schemas.mdx), [emails](../emailing/introduction.md), etc.

Marten projects always use one or many applications. Indeed, each Marten project comes with a default [main application](#the-main-application) that corresponds to the standard `src` folder: models, migrations, or other classes defined in this folder are associated with the main application by default (unless they are part of another _explicitly defined_ application). As projects grow in size and scope, it is generally encouraged to start thinking in terms of applications and how to split models, handlers, or features across multiple apps depending on their intended responsibilities.

Another benefit of applications is that they can be packaged and reused across multiple projects. This allows third-party libraries and shards to easily contribute models, migrations, handlers, or templates to other projects.

## Using applications

The use of applications must be manually enabled within projects: this is done through the use of the [`installed_apps`](./reference/settings.md#installed_apps) setting.

This setting corresponds to an array of installed app classes. Indeed, each Marten application must define a subclass of [`Marten::App`](pathname:///api/0.4/Marten/App.html) to specify a few things such as the application label (see [Creating applications](#creating-applications) for more information about this). When those subclasses are specified in the `installed_apps` setting, the applications' models, migrations, assets, and templates will be made available to the considered project.

For example:

```crystal
Marten.configure do |config|
  config.installed_apps = [
    FooApp,
    BarApp,
  ]
end
```

Adding an application class inside this array will have the following impact on the considered project:

* the models of this application and the associated migrations will be used
* the templates of the application will be made available to the templates engine
* the assets of the application will be made available to the assets engine
* the management commands defined by the application will be made available to the Marten CLI

### The main application

The "main" application is a default application that is always implicitly used by Marten projects (which means that it does not appear in the [`installed_apps`](./reference/settings.md#installed_apps) setting). This application is associated with the standard `src` folder: this means that models, migrations, assets, or templates defined in this folder will be associated with the main application by default. For example, models defined under a `src/models` folder would be associated with the main application.

:::info
The main application is associated with the `main` label. This means that models of the main application that do not define an explicit table name will have table names starting with `main_`.
:::

It should be noted that it is possible to create _explicitly defined_ applications whose structures live under the `src` folder as well: the abstractions (eg. models, migrations, etc) of these applications will be associated with them and _not_ with the main application. This is because abstractions are always associated with the closest application in the files/folders structure.

In the end, the main application provides a convenient way for starting projects and prototyping without requiring to spec out how projects will be organized in terms of applications upfront. That being said, as projects grow in size and scope, it is really encouraged to start thinking in terms of applications and how to split abstractions and features across multiple apps depending on their intended responsibilities.

### Order of installed applications

You should note that the order in which installed applications are defined in the [`installed_apps`](./reference/settings.md#installed_apps) setting can actually matter.

For example, a "foo" app might define a `test.html` template, and a similar template with the exact same name might be defined by a "bar" app. If the "foo" app appears before the "bar" app in the array of installed apps, then requesting and rendering the `test.html` template will actually involve the "foo" app's template only. This is because template loaders associated with app directories iterate over applications in the order in which they are defined in the installed apps array.

This is why it is always important to _namespace_ abstractions, assets, templates, and locales when creating applications. Failing to do so exposes apps to conflicts with other applications' code. As such, in the previous example, the "foo" app should've defined a `foo/test.html` template while the "bar" app should've defined a `bar/test.html` template to avoid possible conflicts.

## Creating applications

Creating applications can be done very easily through the use of the [`app`](./reference/generators.md#app) generator. For example:

```bash
marten gen app blog
```

Running such a command will add a new `blog` application to the current project with the following structure:

```
src/blog
├── emails
├── handlers
├── migrations
├── models
├── schemas
├── templates
├── app.cr
└── cli.cr
```

These files and folders are described below:

| Path | Description |
| ----------- | ----------- |
| `emails/` | Empty directory where the [emails](../emailing/introduction.md) of the application will be defined. |
| `handlers/` | Empty directory where the [request handlers](../handlers-and-http/introduction.md) of the application will be defined. |
| `migrations/` | Empty directory that will store the [migrations](../models-and-databases/migrations.md) that will be generated for the models of the application. |
| `models/` | Empty directory where the [models](../models-and-databases/introduction.md) of the application will be defined. |
| `schemas/` | Empty directory where the [schemas](../schemas/introduction.md) of the application will be defined. |
| `templates/` | Empty directory where the [templates](../templates/introduction.md) of the application will be defined. |
| `app.cr` | Definition of the application configuration abstraction; this is also where application-specific file requirements should be made. |
| `cli.cr` | Requirements of CLI-related files, such as migrations for example. |
| `routes.cr` | Module containing the [routes](../handlers-and-http/routing.md) of the application. |

:::tip
The [`app`](./reference/generators.md#app) generator automatically ensures that:

* The newly created application is added to the [`installed_apps`](./reference/settings.md#installed_apps) setting. 
* Requirements for the application itself are added to the `src/project.cr` and `src/cli.cr` files.
* The application's routes are included in the main routes map (which lives in the `config/routes.cr` file).
:::

The most important file of an application is the `app.cr` one. This file usually includes all the app requirements and defines the application configuration class itself, which must be a subclass of the [`Marten::App`](pathname:///api/0.4/Marten/App.html) abstract class. This class allows mainly to define the "label" identifier of the application (through the use of the [`#label`](pathname:///api/0.4/Marten/Apps/Config.html#label(label%3AString|Symbol)-class-method) class method): this identifier must be unique across all the installed applications of a project and is used to generate things like model table names or migration classes.

Here is an example `app.cr` file content for a hypothetic "blog" app:

```crystal
require "./emails/**"
require "./handlers/**"
require "./models/**"
require "./routes"
require "./schemas/**"

module Blog
  class App < Marten::App
    label "blog"
  end
end
```

:::info
_Where_ the `app.cr` file is located is important: the directory where this file is defined is also the directory where key folders like `models`, `migrations`, `templates`, etc, must be present. This is necessary to ensure that these files and abstractions are associated with the considered app.
:::

Another very important file is the `cli.cr` one: this file is there to define all the CLI-related requirements and will usually be required directly by your project's `manage.cr` file. _A minima_ the `cli.cr` file should require model migrations, but it could also require the management commands provided by the application. For example:

```crystal
require "./cli/**"
require "./migrations/**"
```

### Defining settings for applications

Applications that you create as part of your projects or third-party libraries can have their own associated settings, configurable through the use of regular [settings files](./settings.md).

In order to define settings for your applications, the simplest way is to create a `settings.cr` file containing a subclass of [`Marten::Conf::Settings`](pathname:///api/dev/Marten/Conf/Settings.html) in your application's folder. This subclass must make use of the [`#namespace`](pathname:///api/dev/Marten/Conf/Settings.html#namespace(ns)-macro) macro in order to define the setting "namespace" under which your application's settings will be accessible.

For example:

```crystal
module Blog
  class Settings < Marten::Conf::Settings
    namespace :blog

    @my_setting : String = "foo"

    getter my_setting
    setter my_setting
  end
end
```

With the above example, it will be possible to configure the `blog.my_setting` setting as follows in a project's settings file:

```crystal
Marten.configure do |config|
  config.blog.my_setting = "bar"
end
```

As you can see, the application's settings are configurable like any other built-in settings, but they are namespaced to the namespace value that was defined in the `Blog::Settings` class through the use of the [`#namespace`](pathname:///api/dev/Marten/Conf/Settings.html#namespace(ns)-macro) macro.

It's important to note that [`Marten::Conf::Settings`](pathname:///api/dev/Marten/Conf/Settings.html) subclasses have the flexibility to define any necessary methods to facilitate user configuration for the considered application. While basic settings typically necessitate only getters and setters for configuration, more intricate scenarios may demand additional methods, the utilization of blocks, or other complexities.
