# Your First Project

This guide creates the smallest useful Iwf app. You will generate a project,
change the first page, add a route, add a table, and learn where generated code
goes.

## 1. Generate The App

From the Iwf repository root:

```sh
iwf new my-app
cd my-app
iwf build
./build/exec/my-app
```

Open:

```text
http://127.0.0.1:8080
```

The generated project contains:

| Path | Purpose |
| --- | --- |
| `src/Main.idrx` | The first page, route list, and server entry point. |
| `my-app.ipkg` | The Idris package file for the app. |
| `Application/Schema.sql` | PostgreSQL schema source of truth. |
| `Application/Fixtures.sql` | Development and test seed data. |
| `Application/Migrations/` | Ordered SQL migrations. |
| `build/generated/` | Generated Idris source. Do not edit this by hand. |

## 2. Change The First Page

Open `src/Main.idrx`.

Look for the page view and change the heading:

```idris
homeView : Html
homeView =
  fragment
    [ <title>My App</title>
    , <main id="main-content" class="mx-auto flex max-w-3xl flex-col gap-6 p-6">
        <section class="card">
          <h1>Hello from Iwf</h1>
          <p>Direct .idrx HTML is compiled into checked Idris.</p>
        </section>
      </main>
    ]
```

Rebuild and restart the executable:

```sh
iwf build
./build/exec/my-app
```

The build script preprocesses:

```text
src/Main.idrx -> build/generated/Main.idr
```

Edit `.idrx` files. Do not edit generated `.idr` files under
`build/generated/`.

## 3. Add A Route

Add another view and handler in `src/Main.idrx`:

```idris
aboutView : Html
aboutView =
  fragment
    [ <title>About</title>
    , <main id="main-content" class="mx-auto max-w-3xl p-6">
        <h1>About</h1>
        <p>This page is rendered by Idris on the server.</p>
      </main>
    ]

about : ControllerContext -> Response
about context =
  render context aboutView
```

Add it to the route list:

```idris
export
htmlHomeRoute : RouteSpec NoInput NoInput Response
htmlHomeRoute =
  get "/"

export
htmlHomeBinding : BoundRoute
htmlHomeBinding =
  handledBy htmlHomeRoute home

export
htmlAboutRoute : RouteSpec NoInput NoInput Response
htmlAboutRoute =
  get "/about"

export
htmlAboutBinding : BoundRoute
htmlAboutBinding =
  handledBy htmlAboutRoute about

export
htmlRoutes : Routes
htmlRoutes =
  [ htmlHomeBinding
  , htmlAboutBinding
  ]

appRoutes : Routes
appRoutes =
  htmlRoutes
```

Now visit:

```text
http://127.0.0.1:8080/about
```

Internal links and forms are boosted by default. A direct browser request gets
the framework shell plus this page content. An htmx request gets only the
`#main-content` fragment.

## 4. Link To The New Route

Use the route value instead of spelling the URL again:

```idris
<a class="btn-primary" href={pathTo htmlAboutRoute}>About</a>
```

In a larger app, keep handlerless route specs in `Web/Routes.idr`, keep
executable `handledBy` bindings in `Web/RouteBindings.idr`, and use `pathTo`
from views. That way route changes update links at compile time instead of
becoming broken URLs.

The canonical app shows this style:

```idris
homePath = pathTo htmlHomeRoute
articlePath = pathTo htmlArticleRoute (MkArticleSlugInput article.slug)
```

## 5. Add A Table

Open `Application/Schema.sql` and add:

```sql
CREATE TABLE articles (
  id BIGSERIAL PRIMARY KEY,
  slug TEXT NOT NULL UNIQUE,
  title TEXT NOT NULL,
  body TEXT NOT NULL,
  created_at TIMESTAMP NOT NULL DEFAULT now()
);
```

Rebuild:

```sh
iwf build
```

The starter keeps the schema files in place even before the app uses the
database. The canonical app shows the full schema/typegen flow where
`Application/Schema.sql` generates `Generated.Schema` before compilation.

## 6. What To Study Next

After this starter works, build one full slice with
[First CRUD Feature](first-crud-feature.md). It keeps the code in the
app-facing interface while adding a path route, form, table, TypedSQL query,
validation, auth, and live fragment.

Then study `examples/canonical`. It shows the normal larger app shape:

- `Application/` for schema, queries, mail, jobs, fixtures, and domain code.
- `Web/Routes.idr` for route declarations.
- `Web/Controller/*` for request handlers.
- `Web/View/*.idrx` for HTML.
- `build/generated/` for generated Idris modules.

## Next

Read [First CRUD Feature](first-crud-feature.md).
