
# Manual Installation
This guide will walk you through the process of manually installing Ash into your project.
If you are starting from scratch, you can use `mix new` or `mix igniter.new` and follow these instructions.
These installation instructions apply both to new projects and existing ones.

## Install & Setup Dependencies
See the readmes for `spark` and `reactor` for more information on their installation.
We've included their changes here for your convenience.

Create `.formatter.exs`:
```
# Used by "mix format"
[
  inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"],
  plugins: [Spark.Formatter]
]

```

Create `config/config.exs`:
```
import Config
config :spark, formatter: [remove_parens?: true]

```

Update `mix.exs`:
```diff
...
    defp deps do
      [
+       {:sourceror, "~> 1.8", only: [:dev, :test]}
        # {:dep_from_hexpm, "~> 0.3.0"},
        # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
...
```

Update `.formatter.exs`:
```diff
...
  [
    inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"],
-   plugins: [Spark.Formatter]
+   plugins: [Spark.Formatter],
+   import_deps: [:reactor]
  ]
```

## Skip protocol consolidation
To avoid warnings about protocol consolidation when recompiling in dev, we
set protocol consolidation to happen only in non-dev environments.

## Setup The Formatter
Configure the DSL auto-formatter. This tells the formatter to remove excess parentheses
and how to sort sections in your Ash.Resource & Ash.Domain modules for consistency.

Update `.formatter.exs`:
```diff
...
    inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"],
    plugins: [Spark.Formatter],
-   import_deps: [:reactor]
+   import_deps: [:ash, :reactor]
  ]
```

Update `config/config.exs`:
```diff
  import Config
- config :spark, formatter: [remove_parens?: true]
  
+ config :spark,
+   formatter: [
+     remove_parens?: true,
+     "Ash.Resource": [
+       section_order: [
+         :resource,
+         :code_interface,
+         :actions,
+         :policies,
+         :pub_sub,
+         :preparations,
+         :changes,
+         :validations,
+         :multitenancy,
+         :attributes,
+         :relationships,
+         :calculations,
+         :aggregates,
+         :identities
+       ]
+     ],
+     "Ash.Domain": [section_order: [:resources, :policies, :authorization, :domain, :execution]]
+   ]
+
```

## Configure Dev/Test environments
Configure your dev and test environments
Update `config/config.exs`:
```diff
...
    ]
  
+ import_config "#{config_env()}.exs"
+
```

Create `config/dev.exs`:
```
import Config
config :ash, policies: [show_policy_breakdowns?: true]

```

Create `config/prod.exs`:
```
import Config

```

Create `config/test.exs`:
```
import Config
config :ash, policies: [show_policy_breakdowns?: true]

```

## Setup Backwards Compatibility Configurations
Configure backwards compatibility settings. See the [backwards compatibility guide](https://hexdocs.pm/ash/backwards-compatibility-config.html)
for an explanation of each of the configurations.

Update `config/config.exs`:
```diff
  import Config
  
+ # These enable behaviors that will become the default in the next major
+ # version of Ash. Setting them now opts your application into the new
+ # behavior and ensures a seamless upgrade. See the backwards compatibility
+ # guide for an explanation of each setting:
+ # https://hexdocs.pm/ash/backwards-compatibility-config.html
+ config :ash,
+   allow_forbidden_field_for_relationships_by_default: true,
+   include_embedded_source_by_default?: false,
+   show_keysets_for_all_actions?: false,
+   default_page_type: :keyset,
+   policies: [no_filter_static_forbidden_reads?: false],
+   keep_read_action_loads_when_loading?: false,
+   default_actions_require_atomic?: true,
+   read_action_after_action_hooks_in_order?: true,
+   bulk_actions_default_to_errors?: true,
+   transaction_rollback_on_error?: true,
+   redact_sensitive_values_in_errors?: true,
+   default_string_length_count: :codepoints,
+   infer_generic_action_reactors?: false,
+   many_to_many_destroy_destination_on_match?: true
+ 
  config :spark,
    formatter: [
...
```

## Sign Pagination Keysets
Sign the keysets used for keyset pagination, so that Ash only accepts keysets that it
generated. Each environment gets its own secret. In production, the secret is read from
the `ASH_KEYSET_SIGNING_SECRET` environment variable in `config/runtime.exs`.
You can generate a value with `mix phx.gen.secret` or
`elixir -e ':crypto.strong_rand_bytes(32) |> Base.encode64() |> IO.puts()'`.

If your application uses Phoenix, the production secret is instead derived from Phoenix's
`SECRET_KEY_BASE` environment variable, so there is only one secret to manage.

Update `config/dev.exs`:
```diff
  import Config
- config :ash, policies: [show_policy_breakdowns?: true]
  
+ config :ash,
+   policies: [show_policy_breakdowns?: true],
+   keyset_signing_secret: "<a long random string>"
+
```

Create `config/runtime.exs`:
```
import Config

if config_env() == :prod do
  config :ash,
    keyset_signing_secret:
      System.get_env("ASH_KEYSET_SIGNING_SECRET") ||
        raise("environment variable ASH_KEYSET_SIGNING_SECRET is missing")
end

```

Update `config/test.exs`:
```diff
  import Config
- config :ash, policies: [show_policy_breakdowns?: true]
  
+ config :ash,
+   policies: [show_policy_breakdowns?: true],
+   keyset_signing_secret: "<a long random string>"
+
```

## Register Your Domains
Ash relies on your application's `:ash_domains` configuration to find domain modules for
mix tasks (diagrams, livebooks, policy charts) and to validate that domains/resources are
registered at compile time.

Add your domain modules to `config/config.exs`:

```elixir
config :my_app, :ash_domains, [
  MyApp.Accounts,
  MyApp.Helpdesk
]
```

For more detail, see the [Domains guide](/documentation/topics/resources/domains.md#application-configuration-ash_domains).
