# IHP Framework Overview > Reference notes for implementing the Interaction Hub Framework (IHF) using IHP. > Based on IHP v1.5.0 (released March 2026). --- ## What IHP Is **IHP** (Integrated Haskell Platform) is a batteries-included, full-stack web framework built on Haskell and Nix. Its goal is rapid application development with robust, type-safe code. - **Language:** Haskell (GHC 9.10 default; GHC 9.12 experimental in v1.5) - **Paradigm:** Functional, strongly typed, server-rendered with optional realtime - **Creator:** [digitally induced](https://github.com/digitallyinduced) (Hamburg). Open-sourced 2020, in production since 2017 - **Current version:** v1.5.0 (March 25, 2026) — largest release to date (1,051 commits) - **License:** MIT ### v1.5 Headline Changes | Change | Impact | |--------|--------| | `postgresql-simple` → `hasql` driver | Up to 50% lower query latency | | Dev server RAM: 4 GB → 500–800 MB | Practical on smaller machines | | Session middleware 3×, URL gen 5×, rendering 2× faster | Overall snappier | | `typedSql` quasiquoter | Compile-time SQL type checking against live dev DB | | `fetchPipelined` | Multiple queries in one network round-trip | | Composite primary key support | Needed for join-table models | | Integration test mode | Temporary Postgres DB per test run | | 15+ modules on Hackage separately | `ihp-mail`, `ihp-datasync`, etc. | ### Design Philosophy - Type errors at compile time, not runtime - Single command (`devenv up`) starts a fully self-contained environment — Postgres included, managed by Nix. No Docker, no Kubernetes required - Optimized for AI-assisted development — the type system automatically verifies generated code --- ## Core Architecture ### MVC-Influenced Structure | Layer | IHP Location | Role | |-------|-------------|------| | Model | `Application/Schema.sql` + generated types | Schema, query builder, relationships | | Controller | `Web/Controller/.hs` | Action handlers, parameter binding, DB calls | | View | `Web/View//.hs` | HSX templates, `View` typeclass | | Routing | `Web/Routes.hs` + `Web/FrontController.hs` | URL ↔ action mapping | | Types | `Web/Types.hs` | All controller action constructors | | Helpers | `Application/Helper/Controller.hs`, `Application/Helper/View.hs` | Shared logic | Multi-application support: a single project can contain multiple sub-apps (`Web/`, `Admin/`). `new-application admin` generates an `Admin/` subtree with routes auto-prefixed `/admin/`. ### Type-Safe URL / Action System The IHP router always maps HTTP requests to **data constructors** defined in `Web/Types.hs`: ```haskell data WidgetsController = WidgetsAction | NewWidgetAction | ShowWidgetAction { widgetId :: !(Id Widget) } | CreateWidgetAction | EditWidgetAction { widgetId :: !(Id Widget) } | UpdateWidgetAction { widgetId :: !(Id Widget) } | DeleteWidgetAction { widgetId :: !(Id Widget) } deriving (Eq, Show, Data) ``` - URLs generated from values, not strings: `pathTo ShowWidgetAction { widgetId = someId }` - Compile-time guarantee: broken links are type errors, not 404s - `urlTo` generates absolute URLs (protocol + domain) ### Routing Defined in `Web/Routes.hs`, registered in `Web/FrontController.hs`. **AutoRoute** (most common): `instance AutoRoute WidgetsController` — IHP generates RESTful routes from action name prefixes: | Prefix | HTTP Method | |--------|------------| | `Delete` | DELETE | | `Create`, `Update` | POST/PATCH | | anything else | GET | **Custom routes:** implement `CanRoute` (attoparsec parser URL → action) and `HasPath` (reverse). `customRoutes` overrides individual AutoRoute entries. Supports SEO slugs like `/widgets/my-slug`. HTTP method override for HTML forms: pass `_method=DELETE` (or `PATCH`) as a hidden field. --- ## Development Workflow ### Installation ```bash # 1. Install Determinate Nix (with Flakes + lazy-trees) curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install # 2. Install ihp-new nix profile install nixpkgs#ihp-new # 3. Install direnv and hook into shell nix profile add nixpkgs#direnv echo 'eval "$(direnv hook bash)"' >> ~/.bashrc # or zshrc ``` ### Creating a Project ```bash ihp-new my-project cd my-project devenv up ``` First startup: 10–15 minutes (downloads GHC, Postgres, all Haskell deps via Nix binary cache). Subsequent starts are fast (under 30s). ### Dev Server `devenv up` starts everything: - Application server on `http://localhost:8000` - IHP IDE + Schema Designer on `http://localhost:8001` - Postgres (managed by Nix; no system Postgres needed) - Live reloading (typically sub-50ms after save) ### Project File Structure ``` my-project/ ├── Application/ │ ├── Schema.sql # Single source of truth for all DB types │ ├── Migration/ # -description.sql files │ ├── Helper/ │ │ ├── Controller.hs # Shared controller helpers │ │ └── View.hs # Shared view helpers │ └── Script/ # One-off scripts / cron job binaries ├── Web/ │ ├── Types.hs # ALL controller action constructors │ ├── Routes.hs # AutoRoute instance declarations │ ├── FrontController.hs # WAI entry; dispatch; auth init; default layout │ ├── Controller/ # One file per controller │ ├── View/ # One dir per controller, one file per action │ │ └── Layout.hs # Default layout (Html -> Html) │ └── Component/ # Server-Side Components (optional) ├── Config/ │ ├── Config.hs # Env vars, secrets, feature flags │ └── nix/ │ └── hosts/ │ └── production/ # Declarative NixOS server config ├── Test/ # Integration tests ├── static/ # CSS, JS, images ├── flake.nix # Nix flake — all deps declared here ├── App.cabal # Cabal package definition ├── Main.hs # Entry point └── Makefile # Build targets ``` ### Adding Dependencies In `flake.nix`: ```nix ihp = { enable = true; projectPath = ./.; packages = [ pkgs.imagemagick ]; # native deps haskellPackages = p: [ p.ihp p.aeson p.your-library ]; }; ``` ### Code Generators Navigate to `http://localhost:8001/Generators` or right-click a table in Schema Designer → "Generate Controller". Scaffolds controllers, views, routes, and type entries to match the table's fields. Also available: Migration, Job, Mail, Script generators. ### Testing v1.5: integration test mode creates a temporary Postgres DB automatically per test run. Tests live in `Test/`. --- ## Deployment ### Primary: NixOS / `deploy-to-nixos` The entire server config (nginx, Let's Encrypt, systemd, app config) lives declaratively in `Config/nix/hosts/production/` — version-controlled and reproducible. ```bash deploy-to-nixos production ``` Runs `nixos-rebuild` remotely over SSH. AWS EC2: NixOS AMI, `t3a.small` min (`t3a.medium` recommended), 60 GiB root disk, ports 22/80/443. **Required env vars:** | Variable | Purpose | |----------|---------| | `IHP_SESSION_SECRET` | Session encryption key (`new-session-secret` to generate) | | `DATABASE_URL` | Postgres connection string | | `IHP_BASEURL` | External URL (e.g., `https://example.com`) | **Production features built-in:** - Systemd watchdog (heartbeat 30s; auto-restart after 60s) - Socket activation (queues requests during restarts — zero-downtime deploys) - Sentry integration via `ihp-sentry` (IHP Pro) ### Docker (IHP Pro) ```bash nix build .#unoptimized-docker-image --option sandbox false cat result | podman load ``` Env vars: same as above + `IHP_ASSET_VERSION` (cache-busting) + `IHP_REQUEST_LOGGER_IP_ADDR_SOURCE=FromHeader` (behind load balancer). Minimal Docker images lack CA certificates — copy `caCertificates` and set `SSL_CERT_FILE`. ### Bare Metal Binary ```bash nix build .#optimized-prod-server # full optimisation nix build .#unoptimized-prod-server # faster build, for staging ``` Runtime: `IHP_ENV=Production`, `DATABASE_URL`, `PORT` (default 8000). GHC RTS tunable via `GHCRTS`. ### CSS/JS Bundling ```bash make static/prod.js static/prod.css ``` Dev uses individual files; production uses bundled/minified versions. Background jobs require deploying the `RunJobs` binary alongside the main app. --- ## Key Links - [IHP Homepage](https://ihp.digitallyinduced.com/) - [IHP Guide (full docs)](https://ihp.digitallyinduced.com/Guide/) - [GitHub: digitallyinduced/ihp](https://github.com/digitallyinduced/ihp) - [ihp-boilerplate](https://github.com/digitallyinduced/ihp-boilerplate) — template used by `ihp-new` - [v1.5 release announcement](https://discourse.haskell.org/t/ihp-v1-5-has-been-released/13846)