> For the complete documentation index, see [llms.txt](https://ascribed-dev.com/docs/llms.txt). This documentation describes Ascribe 0.4.5. Anything marked in main, not yet released isn't in that release yet.

# `ascribe init`

> Reference · Start a project with its first ascribe.toml and ascribe.addresses: options, output, and exit codes.

`ascribe init` starts a project: it writes its first `ascribe.toml` and `ascribe.addresses`, and makes the folder its pages go in. [Install Ascribe](https://ascribed-dev.com/docs/install.md#start-a-project) is the task it's used in.

The options every command accepts are in the [command reference](https://ascribed-dev.com/docs/command.md#options-every-command-accepts).

## `ascribe init`

Starts a project: writes its first `ascribe.toml` and `ascribe.addresses`, and makes the folder its pages go in, `docs/`. With `--templates`, it takes the page templates too, as [`ascribe templates eject`](https://ascribed-dev.com/docs/templates/command.md#ascribe-templates-eject) with no name does. In a folder of pages already there, it declares no page types, checks the pages, and says what to run next.

- `[DIR]`: The folder to start the project in, from the current folder. It's made if it isn't there. By default, the current folder.
- `--templates`: Take the page templates too, as `ascribe templates eject` with no name does: six types, beside the type `page`.
- `--content-root <DIR>`: The folder the pages are in, from the project's folder, with `/` between its parts. By default, `docs`. When it holds Markdown already, `ascribe.toml` declares no page types, so no page needs `type:`, and `init` checks the pages and says what to run next. `--templates` declares types, so it's refused there.
- `--dry-run`: Say what it would change, and change nothing.
- `--force`: Change files even when git couldn't put them back as they are: ones with changes not committed, ones git doesn't track, or ones in no repository.
- `--format <FORMAT>`: How to show what was written.
  - `text` (the default): Short text, for people and agents to read.
  - `json`: One JSON document, for tools.

It writes in the current folder, or in `DIR`, a path from the current folder, which it makes if it isn't there. It asks nothing. Where there's an `ascribe.toml` in the folder or above it, it refuses, names the one it found, and writes nothing: `ascribe templates eject`, run there, adds the templates to that project. To start a second project in a repository that has one, name a folder outside it. It takes no `--config`, since the project is the one it starts.

The file it writes is small, and says what each part is for:

```toml
# The project's content model: where its pages are, and what each kind of
# page must say in its frontmatter. `ascribe check` and the editor read it.
# Every section is in the reference: https://ascribed-dev.com/go/content-model/
spec = "0.1"

[project]
# The folder the pages are in. A link that starts with `/` starts here.
content-root = "docs"

# What most projects add next:
#
# - A phrase, such as the product's name, written once here and on a page as
#   {product}: https://ascribed-dev.com/go/phrases/
# - A dimension, such as the reader's platform, for content that's for some
#   readers only: https://ascribed-dev.com/go/dimensions/
# - [consumer], the site the pages are published as, and its address:
#   https://ascribed-dev.com/go/consumer/

# The one kind of page, `page`, with a title and a description. Each page
# says what type it is in its frontmatter: `type: page`.
[types.page.frontmatter]
title = "string"
description = "string"
```

It sets the content root, `docs`, though that's the default, since it's the first thing a project changes; `--content-root` names another, a folder inside the project's. It declares one type, `page`, with a title and a description; since it declares a type, each page names it in its frontmatter, with `type: page`. Its comments name what most projects add next, each with its section of the [`ascribe.toml` reference](https://ascribed-dev.com/docs/content-model.md), and it adds none of them: no site address, no builds, and no [dimensions](https://ascribed-dev.com/docs/glossary.md#dimension).

Beside `ascribe.toml`, it writes `ascribe.addresses`, with no entries yet, so the project [keeps the addresses it publishes](https://ascribed-dev.com/docs/publishing/redirects.md) from its first commit: once a page is published, moving it with `git mv` is [`address-lost`](https://ascribed-dev.com/docs/checks/diagnostics/project-files.md#asc255-address-lost) on the next check against the base, and its fix records the move. It does so in a folder that has pages already, too, and leaves an `ascribe.addresses` that's there as it is.

With `--templates`, the six types are added after `page`, and the templates, their guides, Ascribe's notes, and `templates.lock` are written into `templates/`, as `eject` writes them. When a file is where one would be written, it's named, as `eject` names it, and nothing is written.

Like every [command that writes](https://ascribed-dev.com/docs/command.md#commands-that-write), `init` won't change a file git couldn't put back: it names the file and writes nothing, unless you pass `--force`. It adds files, and changes one that's there only to add the templates to it, so it has little for git to refuse. With `--dry-run`, it says what it would write and make, and writes nothing.

It lists, from the current folder:

- Each file it wrote, `ascribe.toml` and then `ascribe.addresses` last.
- The content root, when it made it.
- With `--templates`, each type it added, as `eject` says it.
- The next step: a first page in the content root, and [`ascribe check`](https://ascribed-dev.com/docs/checks/check.md#ascribe-check).
- Last, the [Astro guide](https://ascribed-dev.com/docs/astro.md), to publish the pages as a site.

```text
wrote ascribe.toml
wrote ascribe.addresses, where a page's move is recorded, so the addresses it published keep working
made docs/, the folder the pages go in
Next, write a first page, docs/index.md, and run `ascribe check`
Then, to publish the pages as a site with Astro, read https://ascribed-dev.com/go/astro-guide/
```

**In a folder of pages.** When the content root holds pages already, `ascribe.toml` declares no page types, so the pages are of the implicit type `page` and none of them needs `type:`. In place of the type, it declares `description` as a field every page can have. `--templates`, whose types each page would have to name, is refused.

Then it checks the pages and says what it found: how many pages, how many have no `title` and how `ascribe check --fix` gives them one, and what [`ascribe check`](https://ascribed-dev.com/docs/checks/check.md#ascribe-check) finds, by code, most first. It ends with what to run next: `--fix`, then the most common code that's left, and [`ascribe baseline write`](https://ascribed-dev.com/docs/checks/baseline.md) when there's advice to record in a [baseline](https://ascribed-dev.com/docs/glossary.md#baseline). It exits with 0 whatever the check finds, since the project is there. [Bring existing docs to Ascribe](https://ascribed-dev.com/docs/existing-docs.md) goes through it, step by step:

```text
wrote ascribe.toml
wrote ascribe.addresses, where a page's move is recorded, so the addresses it published keep working
found 4 pages in docs/; with no page types declared in ascribe.toml, no page needs `type:`
3 pages have no `title`; `ascribe check --fix` takes the opening heading as the title of 2 of them, and the rest need `title:` written in their frontmatter
`ascribe check` finds 4 errors, 0 warnings, 5 advice:
  3  ASC048 frontmatter-missing-field (error)
  3  ASC150 page-description-missing (advice)
  2  ASC151 heading-level-skipped (advice)
  1  ASC036 link-target-missing (error)
Next, run `ascribe check --fix`, which fixes 2 of them, then `ascribe check --code ASC048`
To put the advice off, so the check reports only what's new: `ascribe baseline write`
Then, to publish the pages as a site with Astro, read https://ascribed-dev.com/go/astro-guide/
```

With `--format json`, it writes the document its [schema](https://ascribed-dev.com/docs/contracts/json-reports/model.md#ascribe-init) describes. When `templates.refused` isn't empty, `written` is empty.

**The JSON for this example**

```json
{
  "schema_version": 2,
  "ascribe_version": "{version}",
  "written": [
    "ascribe.toml",
    "ascribe.addresses"
  ],
  "dry_run": false,
  "content_root": "docs",
  "content_root_made": true,
  "pages": 0,
  "templates": null,
  "next": "https://ascribed-dev.com/go/astro-guide/"
}
```

| Code | Meaning |
| --- | --- |
| `0` | The project is there: `ascribe.toml` and `ascribe.addresses` are written, the content root is there, and with `--templates`, every template and its type |
| `2` | It wrote nothing: there's an `ascribe.toml` in the folder or above it, the folder is a file, `--content-root` isn't a folder inside the project's, `--templates` was given in a folder of pages, a template was refused, it was given `--config`, or, without `--force`, a file git couldn't put back. Or a file couldn't be written; the files it wrote before that stay. |

## See also

- [Getting started](https://ascribed-dev.com/docs/getting-started.md): a first project, from `npm install` to a built page.
- [Bring existing docs to Ascribe](https://ascribed-dev.com/docs/existing-docs.md): a project around a folder of Markdown you have.
