# Introducing Concoct - A declarative UI framework

**URL:** <https://discourse.haskell.org/t/introducing-concoct-a-declarative-ui-framework/13630>\
**Category:** Announcements\
**Created:** [January 31, 2026, 7:04pm UTC](https://discourse.haskell.org/t/introducing-concoct-a-declarative-ui-framework/13630 "2026-01-31T19:04:10Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![matthunz](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/matthunz/32/4980_2.png) [@matthunz](https://discourse.haskell.org/u/matthunz)\
**Post date:** [January 31, 2026, 7:04pm UTC](https://discourse.haskell.org/t/introducing-concoct-a-declarative-ui-framework/13630/1 "2026-01-31T19:04:10Z")

</div>

I’m excited to introduce Concoct, a new declarative user-interface framework for Haskell.

```haskell
counter :: (MonadView IO m) => m ()
counter = do
  count <- useState $ pure (0 :: Int)

  useEffect (readStateRef count) $ \c -> do
    putStrLn $ "Count: " ++ show c
    writeStateRef count $ c + 1

  switchView
    (even <$> readStateRef count)
    (liftView $ putStrLn "Even!")
    (liftView $ putStrLn "Odd!")

  useOnUnmount $ do
    c <- readStateRef count
    putStrLn $ "Unmount:" ++ show c

```

> **[GitHub - matthunz/concoct: A reactive UI framework for Haskell](https://github.com/matthunz/concoct)**
>
> A reactive UI framework for Haskell

I’ve been playing around with how to do proper declarative UI for awhile now, first in Rust and then Haskell. I finally feel like I found an interesting pattern that works similarly to [ReactJS](https://react.dev/) but with type-safety for hooks and other things that get tricky in React.

By running the main `MonadView` in multiple passes, similar to how [Reflex](https://reflex-frp.org/) handles FRP, the actual structure of the UI can be guaranteed to be the same across renders, so it’s impossible to improperly use hooks. More info on the [Hackage docs](https://hackage-content.haskell.org/package/concoct-0.1.0/docs/Concoct-View.html)

---

<div class="post-metadata">

**Author:** ![pmidden](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/pmidden/32/2426_2.png) [@pmidden](https://discourse.haskell.org/u/pmidden)\
**Post date:** [February 2, 2026, 7:00am UTC](https://discourse.haskell.org/t/introducing-concoct-a-declarative-ui-framework/13630/2 "2026-02-02T07:00:41Z")

</div>

This feels like a fundamental building block for something bigger, but I cannot really place it. It has no UI dependencies (vty, gtk, qt, …), how is it intended to be used?

---

<div class="post-metadata">

**Author:** ![gtf21](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/gtf21/32/5210_2.png) [@gtf21](https://discourse.haskell.org/u/gtf21)\
**Post date:** [February 6, 2026, 12:39pm UTC](https://discourse.haskell.org/t/introducing-concoct-a-declarative-ui-framework/13630/3 "2026-02-06T12:39:25Z")

</div>

I think hooks are the worst thing the react team ever introduced. It makes it so hard to understand the effects of your code. Why introduce them here?

---

<div class="post-metadata">

**Author:** ![matthunz](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/matthunz/32/4980_2.png) [@matthunz](https://discourse.haskell.org/u/matthunz)\
**Post date:** [February 12, 2026, 4:07am UTC](https://discourse.haskell.org/t/introducing-concoct-a-declarative-ui-framework/13630/4 "2026-02-12T04:07:33Z")

</div>

I might’ve published it a little too early 😅 it should be possible to wire up rendering but I’m hoping to use this as a frontend for the [aztecs](https://github.com/aztecs-hs/aztecs) game engine soon

---

<div class="post-metadata">

**Author:** ![matthunz](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/matthunz/32/4980_2.png) [@matthunz](https://discourse.haskell.org/u/matthunz)\
**Post date:** [February 12, 2026, 4:09am UTC](https://discourse.haskell.org/t/introducing-concoct-a-declarative-ui-framework/13630/5 "2026-02-12T04:09:20Z")

</div>

I like hooks! But I agree in React they can be pretty rough. I’m hoping concoct’s type-safety can eliminate a lot of the annoyance with hooks, and even make them more interesting by having everything essentially be a hook (no major difference from a component and hook) let Android’s Jetpack Compose does. Basically since hooks are guaranteed to run in order, you don’t have to manually enforce hook rules like React, and so they can actually be the primitive for all reactivity
