diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,22 @@
+# Changelog
+
+## 0.5.0 — 2026-08-27
+
+### Breaking
+- Require GHC 9.6+ / `base >= 4.14` (0.4.1 supported GHC 7.6+)
+
+### Changed
+- Support `ditto >= 0.4 && < 0.6` (backwards compatible with 0.4.x)
+- Modernize cabal file (cabal 3.0, stricter warnings, `tested-with`)
+- Relax `lucid` upper bound to `< 4`
+- Move language extensions from modules into the cabal file
+- Public API and type signatures unchanged (compatible with ditto 0.4.x)
+
+### Added
+- README and CHANGELOG
+- GitHub Actions CI for GHC 9.6–9.14 × ditto 0.4 (Hackage) and 0.5 (master)
+- `cabal.project.local.example` for sibling `../ditto` development
+
+### Removed
+- `Setup.hs` (unused with `build-type: Simple`)
+- Travis CI configuration
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,33 @@
+ditto-lucid [![Hackage](https://img.shields.io/hackage/v/ditto-lucid.svg)](https://hackage.haskell.org/package/ditto-lucid)
+===========
+
+Lucid HTML rendering for [ditto](https://github.com/goolord/ditto) forms.
+
+## Requirements
+
+- GHC 9.6 through 9.14 (`base >= 4.14`). GHC 9.10+ uses `GHC2024` by default.
+- Works with **ditto 0.4** and **0.5** (backwards compatible).
+
+### Cabal
+
+```
+cabal build
+```
+
+Resolves `ditto` from Hackage (`>= 0.4 && < 0.6`).
+
+### Local ditto development
+
+To build against a sibling checkout instead of Hackage:
+
+```
+cp cabal.project.local.example cabal.project.local
+cabal build
+```
+
+## 0.5.0 notes
+
+- **Breaking:** GHC 9.6+ required (was GHC 7.6+ on 0.4.1).
+- Compatible with `ditto >= 0.4`.
+- Recommended toolchain: GHC 9.10+ for `GHC2024`.
+- With ditto 0.5+, `inputFile` initial render is an empty upload (no error).
diff --git a/Setup.hs b/Setup.hs
deleted file mode 100644
--- a/Setup.hs
+++ /dev/null
@@ -1,2 +0,0 @@
-import Distribution.Simple
-main = defaultMain
diff --git a/cabal.project.local.example b/cabal.project.local.example
new file mode 100644
--- /dev/null
+++ b/cabal.project.local.example
@@ -0,0 +1,3 @@
+packages:
+  ./
+  ../ditto
diff --git a/ditto-lucid.cabal b/ditto-lucid.cabal
--- a/ditto-lucid.cabal
+++ b/ditto-lucid.cabal
@@ -1,31 +1,76 @@
-Name:                ditto-lucid
-Version:             0.4
-Synopsis:            Add support for using lucid with Ditto
-Description:         Ditto is a library for building and validating forms using applicative functors. This package add support for using ditto with lucid.
-License:             BSD3
-License-file:        LICENSE
-Author:              Jeremy Shaw, Zachary Churchill
-Maintainer:          zacharyachurchill@gmail.com
-Copyright:           2012 Jeremy Shaw, SeeReason Partners LLC,
-                     2019 Zachary Churchill
-Category:            Web
-Build-type:          Simple
-Cabal-version:       >=1.6
+cabal-version: 3.0
+name: ditto-lucid
+version: 0.5.0
+synopsis: Add support for using lucid with Ditto
+description:
+  Ditto is a library for building and validating forms using applicative
+  functors. This package adds support for using Ditto with Lucid.
+license: BSD-3-Clause
+license-file: LICENSE
+author: Jeremy Shaw, Zachary Churchill
+maintainer: zacharyachurchill@gmail.com
+copyright:
+  2012 Jeremy Shaw, SeeReason Partners LLC,
+  2019 Zachary Churchill
+homepage: https://github.com/goolord/ditto-lucid
+bug-reports: https://github.com/goolord/ditto-lucid/issues
+category: Web
+build-type: Simple
+extra-doc-files:
+  CHANGELOG.md
+  README.md
+  cabal.project.local.example
+tested-with:
+  GHC == 9.6.7
+  GHC == 9.8.4
+  GHC == 9.10.3
+  GHC == 9.12.4
+  GHC == 9.14.1
 
 source-repository head
-  type:     git
+  type: git
   location: https://github.com/goolord/ditto-lucid.git
 
-Library
+common warnings-base
   ghc-options: -Wall
-  exposed-modules: 
+
+common warnings-modern
+  if impl(ghc >= 8.10)
+    ghc-options:
+      -Wcompat
+      -Widentities
+      -Wincomplete-record-updates
+      -Wincomplete-uni-patterns
+      -Wmissing-deriving-strategies
+      -Wunused-packages
+
+common extensions-shared
+  default-extensions:
+    OverloadedStrings
+    ScopedTypeVariables
+    TypeFamilies
+
+common defaults-ghc2024
+  import: warnings-base, warnings-modern, extensions-shared
+  default-language: GHC2024
+
+common defaults-ghc2021
+  import: warnings-base, warnings-modern, extensions-shared
+  default-language: GHC2021
+
+library
+  if impl(ghc >= 9.10)
+    import: defaults-ghc2024
+  else
+    import: defaults-ghc2021
+  exposed-modules:
     Ditto.Lucid
     Ditto.Lucid.Unnamed
     Ditto.Lucid.Named
   build-depends:
-      base >4.5 && <5
-    , lucid < 3.0.0
-    , ditto >= 0.4 && <= 0.5
-    , text >= 0.11 && < 1.3
-    , path-pieces
+      base        >= 4.14 && < 5
+    , lucid       >= 2.9  && < 4
+    , ditto       >= 0.4  && < 0.6
+    , text        >= 1.2  && < 3
+    , path-pieces >= 0.2  && < 0.4
   hs-source-dirs: src
diff --git a/src/Ditto/Lucid.hs b/src/Ditto/Lucid.hs
--- a/src/Ditto/Lucid.hs
+++ b/src/Ditto/Lucid.hs
@@ -1,7 +1,3 @@
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE TypeFamilies #-}
-
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 
 module Ditto.Lucid where
diff --git a/src/Ditto/Lucid/Named.hs b/src/Ditto/Lucid/Named.hs
--- a/src/Ditto/Lucid/Named.hs
+++ b/src/Ditto/Lucid/Named.hs
@@ -1,7 +1,3 @@
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE TypeFamilies #-}
-
 module Ditto.Lucid.Named where
 
 import Data.Foldable (traverse_, fold)
diff --git a/src/Ditto/Lucid/Unnamed.hs b/src/Ditto/Lucid/Unnamed.hs
--- a/src/Ditto/Lucid/Unnamed.hs
+++ b/src/Ditto/Lucid/Unnamed.hs
@@ -1,7 +1,3 @@
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE TypeFamilies #-}
-
 module Ditto.Lucid.Unnamed where
 
 import Data.Foldable (traverse_, fold)
