diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,3 @@
+# 0.1.0
+
+  * Initial version.
diff --git a/Control/Wire.hs b/Control/Wire.hs
new file mode 100644
--- /dev/null
+++ b/Control/Wire.hs
@@ -0,0 +1,17 @@
+-- |
+-- Copyright:  (c) 2016 Ertugrul Söylemez
+-- License:    BSD3
+-- Maintainer: Ertugrul Söylemez <esz@posteo.de>
+-- Stability:  experimental
+
+module Control.Wire
+    ( -- * Wires
+      module Control.Category,
+      module Control.Wire.Core,
+      module Control.Wire.Utils
+    )
+    where
+
+import Control.Category
+import Control.Wire.Core
+import Control.Wire.Utils
diff --git a/Control/Wire/Controller.hs b/Control/Wire/Controller.hs
new file mode 100644
--- /dev/null
+++ b/Control/Wire/Controller.hs
@@ -0,0 +1,48 @@
+-- |
+-- Copyright:  (c) 2016 Ertugrul Söylemez
+-- License:    BSD3
+-- Maintainer: Ertugrul Söylemez <esz@posteo.de>
+-- Stability:  experimental
+
+{-# LANGUAGE TupleSections #-}
+
+module Control.Wire.Controller
+    ( -- * Controllers
+      animate,
+      control,
+      newEvent,
+      onEvent,
+      stepWire
+    )
+    where
+
+import Control.Wire.Internal
+
+
+-- | Run the given action in every frame.
+
+animate :: (Applicative m) => Wire m (m a) a
+animate = let w = Wire (fmap (, w)) in w
+
+
+-- | Run the given wire until its result event occurs.
+
+control :: (Monad m) => Wire m () (Event b) -> m b
+control w' = do
+    (mx, w) <- stepWire w' ()
+    event (control w) pure mx
+
+
+-- | Construct an event from the given polling function.
+
+newEvent :: (Functor m) => Wire m (m (Maybe b)) (Event b)
+newEvent = Wire $ fmap (\mx -> (maybe NotNow Now mx, newEvent))
+
+
+-- | Run the given action whenever the given event occurs.
+
+onEvent :: (Applicative m) => Wire m (Event (m a)) (Event a)
+onEvent =
+    Wire $
+    event (pure (NotNow, onEvent))
+          (fmap $ \x -> (Now x, onEvent))
diff --git a/Control/Wire/Core.hs b/Control/Wire/Core.hs
new file mode 100644
--- /dev/null
+++ b/Control/Wire/Core.hs
@@ -0,0 +1,157 @@
+-- |
+-- Copyright:  (c) 2016 Ertugrul Söylemez
+-- License:    BSD3
+-- Maintainer: Ertugrul Söylemez <esz@posteo.de>
+-- Stability:  experimental
+
+{-# LANGUAGE RankNTypes #-}
+
+module Control.Wire.Core
+    ( -- * Wires
+      Wire,
+      evalWith,
+      initial,
+      withM,
+
+      -- * Events
+      Event,
+      catMapE,
+      hold,
+      hold',
+      never,
+      unfoldE,
+
+      -- * Switching
+      manage,
+      manage',
+      sequenceW,
+      switch,
+      switch'
+    )
+    where
+
+import Control.Wire.Internal
+
+
+-- | Map and filter event occurrences using the given function.
+
+catMapE :: (a -> Maybe b) -> Event a -> Event b
+catMapE f = event NotNow (maybe NotNow Now . f)
+
+
+-- | Evaluate the input using the given strategy in every frame.  Valid
+-- arguments include functions like `seq`.
+
+evalWith :: (Applicative m) => (forall b. a -> b -> b) -> Wire m a a
+evalWith strat = let w = Wire (\x -> x `strat` pure (x, w)) in w
+
+
+-- | Hold the latest occurrence of the given event starting with the
+-- given initial value.  The value switch occurs in the next frame.
+
+hold :: (Applicative m) => a -> Wire m (Event a) a
+hold x' = delayW x' (hold' x')
+
+
+-- | Hold the latest occurrence of the given event starting with the
+-- given initial value.  The value switch occurs instantly.
+
+hold' :: (Applicative m) => a -> Wire m (Event a) a
+hold' x' = Wire $ (\x -> pure (x, hold' x)) . event x' id
+
+
+-- | Run the given action once at the beginning.
+
+initial :: (Applicative m) => Wire m (m a) a
+initial = Wire $ fmap (\y -> (y, pure y))
+
+
+-- | Sequence each of the given wires and collect their results.  If the
+-- given event occurs, the its function is applied to the current set of
+-- wires.  Changes are applied in the next frame.
+
+manage
+    :: (Traversable f, Applicative m)
+    => f (Wire m a b)
+    -> Wire m (a, Event (f (Wire m a b) -> f (Wire m a b))) (f b)
+manage ws' =
+    Wire $ \(x, mf) ->
+        (\ys -> (fst <$> ys,
+                 manage (event id id mf (snd <$> ys))))
+        <$> traverse (`stepWire` x) ws'
+
+
+-- | Sequence each of the given wires and collect their results.  If the
+-- given event occurs, the its function is applied to the current set of
+-- wires.  Changes are applied immediately.
+
+manage'
+    :: (Traversable f, Applicative m)
+    => f (Wire m a b)
+    -> Wire m (a, Event (f (Wire m a b) -> f (Wire m a b))) (f b)
+manage' ws' =
+    Wire $ \(x, mf) ->
+        (\ys -> (fst <$> ys,
+                 manage (snd <$> ys)))
+        <$> traverse (`stepWire` x) (event id id mf ws')
+
+
+-- | The event that never occurs.
+
+never :: Event a
+never = NotNow
+
+
+-- | Sequence each of the given wires and collect their results.
+
+sequenceW :: (Traversable f, Applicative m) => f (Wire m a b) -> Wire m a (f b)
+sequenceW ws' =
+    Wire $ \x ->
+        (\ys -> (fst <$> ys,
+                 sequenceW (snd <$> ys)))
+        <$> traverse (\w' -> stepWire w' x) ws'
+
+
+-- | Acts like the given wire until its event occurs, then switches to
+-- the wire the occurrence contained.  The switch occurs in the next
+-- frame.
+
+switch :: (Functor m) => Wire m a (b, Event (Wire m a b)) -> Wire m a b
+switch w' =
+    Wire $ \x ->
+        (\((y, mw), w) -> (y, event (switch w) id mw))
+        <$> stepWire w' x
+
+
+-- | Acts like the given wire until its event occurs, then switches to
+-- the wire the occurrence contained.  The switch occurs immediately.
+
+switch' :: (Monad m) => Wire m a (b, Event (Wire m a b)) -> Wire m a b
+switch' w' =
+    Wire $ \x -> do
+        ((y, mw), w) <- stepWire w' x
+        case mw of
+          NotNow -> pure (y, switch w)
+          Now nw -> stepWire nw x
+
+
+-- | Unfold the given event using the state transition functions it
+-- carries.
+
+unfoldE :: (Applicative m) => s -> Wire m (Event (s -> (a, s))) (Event a)
+unfoldE s' =
+    Wire $ \mf ->
+        pure (case mf of
+                NotNow -> (NotNow, unfoldE s')
+                Now f  -> let (x, s) = f s' in (Now x, unfoldE s))
+
+
+-- | Run the given action to initialise the given wire.  Example:
+--
+-- > withM (scan f) actionFromInitialInput
+
+withM :: (Monad m) => (s -> Wire m a b) -> (a -> m s) -> Wire m a b
+withM w f =
+    Wire $ \x -> do
+        s0 <- f x
+        stepWire (w s0) x
diff --git a/Control/Wire/Internal.hs b/Control/Wire/Internal.hs
new file mode 100644
--- /dev/null
+++ b/Control/Wire/Internal.hs
@@ -0,0 +1,203 @@
+-- |
+-- Copyright:  (c) 2016 Ertugrul Söylemez
+-- License:    BSD3
+-- Maintainer: Ertugrul Söylemez <esz@posteo.de>
+-- Stability:  experimental
+
+{-# LANGUAGE DeriveFunctor #-}
+
+module Control.Wire.Internal
+    ( -- * Wires
+      Wire(..),
+      delayW,
+
+      -- * Events
+      Event(..),
+      event
+    )
+    where
+
+import Control.Arrow
+import Control.Category
+import Control.DeepSeq
+import Control.Monad.Fix
+import Data.Align
+import Data.Functor.Bind
+import Data.Functor.Extend
+import Data.Functor.Plus
+import Data.Profunctor
+import Data.These
+import Prelude hiding ((.), id)
+
+
+-- | An event is a timestamped stream of occurrences with payloads of
+-- the given type.
+
+data Event a
+    = NotNow  -- ^ Not in this frame.
+    | Now a   -- ^ In this frame with the given value.
+    deriving (Functor)
+
+instance Align Event where
+    nil = NotNow
+
+    alignWith f (Now x) (Now y) = Now (f (These x y))
+    alignWith f (Now x) _       = Now (f (This x))
+    alignWith f _       (Now y) = Now (f (That y))
+    alignWith _ _       _       = NotNow
+
+instance Alt Event where
+    (<!>) = alignWith (mergeThese const)
+
+instance Apply Event where
+    Now f  <.> Now x  = Now (f x)
+    _      <.> _      = NotNow
+
+instance Bind Event where
+    Now x  >>- f = event NotNow Now (f x)
+    NotNow >>- _ = NotNow
+
+    join (Now (Now x)) = Now x
+    join _             = NotNow
+
+instance Extend Event where
+    duplicated = event NotNow (Now . Now)
+    extended f = event NotNow (Now . f . Now)
+
+instance (Monoid a) => Monoid (Event a) where
+    mappend = alignWith (mergeThese mappend)
+    mempty  = nil
+
+instance (NFData a) => NFData (Event a) where
+    rnf NotNow = ()
+    rnf (Now x) = rnf x
+
+instance Plus Event where
+    zero = nil
+
+
+-- | 'Wire' is a language for defining reactive systems.  It is similar
+-- to the underlying monad @m@, but runs continuously.
+
+newtype Wire m a b =
+    Wire {
+      -- | Run a single frame of the given wire.
+      stepWire :: a -> m (b, Wire m a b)
+    }
+    deriving (Functor)
+
+instance (Applicative m) => Applicative (Wire m a) where
+    pure x = let w = Wire (\_ -> pure (x, w)) in w
+
+    wf' <*> wx' =
+        Wire $ \x' ->
+            (\(f, wf) (x, wx) -> (f x, wf <*> wx))
+            <$> stepWire wf' x'
+            <*> stepWire wx' x'
+
+instance (Monad m) => Arrow (Wire m) where
+    arr f = let w = Wire (\x -> pure (f x, w)) in w
+    first = first'
+    second = second'
+
+    wx' &&& wy' =
+        Wire $ \x' ->
+            (\(x, wx) (y, wy) -> ((x, y), wx &&& wy))
+            <$> stepWire wx' x'
+            <*> stepWire wy' x'
+
+    wx' *** wy' =
+        Wire $ \(x', y') ->
+            (\(x, wx) (y, wy) -> ((x, y), wx *** wy))
+            <$> stepWire wx' x'
+            <*> stepWire wy' y'
+
+instance (Monad m) => ArrowChoice (Wire m) where
+    left = left'
+    right = right'
+
+    wl' +++ wr' =
+        Wire $
+        either (\x -> (\(y, wl) -> (Left y,  wl +++ wr')) <$> stepWire wl' x)
+               (\x -> (\(y, wr) -> (Right y, wl' +++ wr)) <$> stepWire wr' x)
+
+    wl' ||| wr' =
+        Wire $
+        either (\x -> (\(y, wl) -> (y, wl ||| wr')) <$> stepWire wl' x)
+               (\x -> (\(y, wr) -> (y, wl' ||| wr)) <$> stepWire wr' x)
+
+instance (MonadFix m) => ArrowLoop (Wire m) where
+    loop = unfirst
+
+instance (Monad m) => Category (Wire m) where
+    id = let w = Wire (\x -> pure (x, w)) in w
+
+    w2' . w1' =
+        Wire $ \x0 -> do
+            (x1, w1) <- stepWire w1' x0
+            (x2, w2) <- stepWire w2' x1
+            pure (x2, w2 . w1)
+
+instance (Applicative m) => Choice (Wire m) where
+    left' w' =
+        Wire $
+        either (\x -> (\(y, w) -> (Left y, left' w)) <$> stepWire w' x)
+               (\x -> pure (Right x, left' w'))
+
+    right' w' =
+        Wire $
+        either (\x -> pure (Left x, right' w'))
+               (\x -> (\(y, w) -> (Right y, right' w)) <$> stepWire w' x)
+
+instance (MonadFix m) => Costrong (Wire m) where
+    unfirst w' =
+        Wire $ \x' ->
+            (\((x, _), w) -> (x, unfirst w))
+            <$> mfix (\r -> stepWire w' (x', snd (fst r)))
+
+    unsecond w' =
+        Wire $ \x' ->
+            (\((_, x), w) -> (x, unsecond w))
+            <$> mfix (\r -> stepWire w' (fst (fst r), x'))
+
+instance (Functor m) => Profunctor (Wire m) where
+    dimap fl fr = go
+        where
+        go w' = Wire (fmap (\(y, w) -> (fr y, go w)) . stepWire w' . fl)
+
+    lmap f = go
+        where
+        go w' = Wire (fmap (\(y, w) -> (y, go w)) . stepWire w' . f)
+
+    rmap = fmap
+
+instance (Functor m) => Strong (Wire m) where
+    first' w' =
+        Wire $ \(x', y) ->
+            (\(x, w) -> ((x, y), first' w))
+            <$> stepWire w' x'
+
+    second' w' =
+        Wire $ \(x, y') ->
+            (\(y, w) -> ((x, y), second' w))
+            <$> stepWire w' y'
+
+
+-- | Delay the result of the given wire by one frame.
+
+delayW :: (Functor m) => b -> Wire m a b -> Wire m a b
+delayW y' w' =
+    Wire $ \x ->
+        (\(y, w) -> (y', delayW y w))
+        <$> stepWire w' x
+
+
+-- | Fold the given event.
+
+event
+    :: r         -- ^ Not now.
+    -> (a -> r)  -- ^ Now.
+    -> Event a   -- ^ Event to fold.
+    -> r
+event k _ NotNow  = k
+event _ k (Now x) = k x
diff --git a/Control/Wire/Utils.hs b/Control/Wire/Utils.hs
new file mode 100644
--- /dev/null
+++ b/Control/Wire/Utils.hs
@@ -0,0 +1,56 @@
+-- |
+-- Copyright:  (c) 2016 Ertugrul Söylemez
+-- License:    BSD3
+-- Maintainer: Ertugrul Söylemez <esz@posteo.de>
+-- Stability:  experimental
+
+module Control.Wire.Utils
+    ( -- * Wire utilities
+      withM_,
+
+      -- * Event utilities
+      filterE,
+      scan,
+      scan',
+      scanE
+    )
+    where
+
+import Control.Category
+import Control.Wire.Core
+import Data.Profunctor
+import Prelude hiding ((.), id)
+
+
+-- | Filter event occurrences using the given function.
+
+filterE :: (a -> Bool) -> Event a -> Event a
+filterE p = catMapE (\x -> if p x then Just x else Nothing)
+
+
+-- | Left scan and hold of the given event.
+
+scan :: (Monad m) => a -> Wire m (Event (a -> a)) a
+scan x0 = hold x0 . scanE x0
+
+
+-- | Left scan and hold of the given event.  The value switch occurs
+-- instantly.
+
+scan' :: (Monad m) => a -> Wire m (Event (a -> a)) a
+scan' x0 = hold' x0 . scanE x0
+
+
+-- | Left scan of the given event.
+
+scanE :: (Applicative m) => a -> Wire m (Event (a -> a)) (Event a)
+scanE = lmap (fmap $ \f x -> let y = f x in (y, y)) . unfoldE
+
+
+-- | Run the given action to initialise the given wire.  Simplified
+-- variant of 'withM'.  Example:
+--
+-- > withM_ (scan f) action
+
+withM_ :: (Monad m) => (s -> Wire m a b) -> m s -> Wire m a b
+withM_ w c = withM w (const c)
diff --git a/Control/Wire/Varying.hs b/Control/Wire/Varying.hs
new file mode 100644
--- /dev/null
+++ b/Control/Wire/Varying.hs
@@ -0,0 +1,155 @@
+-- |
+-- Copyright:  (c) 2016 Ertugrul Söylemez
+-- License:    BSD3
+-- Maintainer: Ertugrul Söylemez <esz@posteo.de>
+-- Stability:  experimental
+
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE DeriveFoldable #-}
+{-# LANGUAGE DeriveFunctor #-}
+
+module Control.Wire.Varying
+    ( -- * Time-varying values
+      Varying,
+      changes,
+      value,
+
+      -- * Events
+      holdV,
+      holdV',
+      scanV,
+
+      -- * Controllers
+      animateV
+    )
+    where
+
+import Control.Applicative
+import Control.DeepSeq
+import Control.Monad
+import Control.Wire.Internal
+import Data.String
+#if MIN_VERSION_base(4,9,0)
+import Numeric
+#endif
+
+
+-- | A 'Varying' is a behaviour combined with an event that tracks when
+-- the value changes.
+
+data Varying a = Varying !Bool !a
+    deriving (Foldable, Functor)
+
+instance Applicative Varying where
+    pure = Varying False
+    (<*>) = ap
+
+instance (Bounded a) => Bounded (Varying a) where
+    minBound = pure minBound
+    maxBound = pure maxBound
+
+instance (NFData a) => NFData (Varying a) where
+    rnf (Varying _ x) = rnf x
+
+instance (Floating a) => Floating (Varying a) where
+    (**) = liftA2 (**)
+    pi = pure pi
+    exp = fmap exp
+    log = fmap log
+    sqrt = fmap sqrt
+    logBase = liftA2 logBase
+
+    sin = fmap sin; asin = fmap asin; sinh = fmap sinh; asinh = fmap asinh
+    cos = fmap cos; acos = fmap acos; cosh = fmap cosh; acosh = fmap acosh
+    tan = fmap tan; atan = fmap atan; tanh = fmap tanh; atanh = fmap atanh
+
+#if MIN_VERSION_base(4,9,0)
+    log1p = fmap log1p
+    expm1 = fmap expm1
+    log1pexp = fmap log1pexp
+    log1mexp = fmap log1mexp
+#endif
+
+instance (Fractional a) => Fractional (Varying a) where
+    (/) = liftA2 (/)
+    fromRational = pure . fromRational
+    recip = fmap recip
+
+instance (IsString a) => IsString (Varying a) where
+    fromString = pure . fromString
+
+instance Monad Varying where
+    Varying cx x >>= f =
+        let Varying cy y = f x
+        in Varying (cx || cy) y
+
+instance (Num a) => Num (Varying a) where
+    (+) = liftA2 (+)
+    (-) = liftA2 (-)
+    (*) = liftA2 (*)
+    abs = fmap abs
+    fromInteger = pure . fromInteger
+    negate = fmap negate
+    signum = fmap signum
+
+
+-- | Run the given action each time the given time-varying value
+-- changes.
+
+animateV :: (Applicative m) => (a -> m b) -> Wire m (Varying a) (Varying b)
+animateV f =
+    Wire $ \(Varying cx x) -> do
+        (\y -> (Varying cx y, go y))
+        <$> f x
+
+    where
+    go y' =
+        Wire $ \(Varying cx x) ->
+            if cx
+              then (\y -> (Varying True y, go y)) <$> f x
+              else pure (Varying False y', go y')
+
+
+-- | The change event of the given time-varying value.
+
+changes :: Varying a -> Event a
+changes (Varying cx x) = if cx then Now x else NotNow
+
+
+-- | Hold the latest occurrence of the given event starting with the
+-- given initial value.  The value switch occurs in the next frame.
+
+holdV :: (Applicative m) => a -> Wire m (Event a) (Varying a)
+holdV = go . Varying False
+    where
+    go x' =
+        Wire $ \mx ->
+            pure (x', go (event (Varying False (value x')) (Varying True) mx))
+
+
+-- | Hold the latest occurrence of the given event starting with the
+-- given initial value.  The value switch occurs instantly.
+
+holdV' :: (Applicative m) => a -> Wire m (Event a) (Varying a)
+holdV' x' =
+    Wire $ \mx ->
+        pure $
+        case mx of
+          NotNow -> (Varying False x', holdV' x')
+          Now x  -> (Varying True x, holdV' x)
+
+
+-- | Left scan and hold of the given event.
+
+scanV :: (Applicative m) => (a -> b -> b) -> b -> Wire m (Event a) (Varying b)
+scanV f = go . Varying False
+    where
+    go x' =
+        Wire $ \mdx ->
+            pure (x', go (event (Varying False) (\dx -> Varying True . f dx) mdx (value x')))
+
+
+-- | The behaviour value of the given time-varying value.
+
+value :: Varying a -> a
+value (Varying _ x) = x
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,27 @@
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    (1) Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+
+    (2) Redistributions in binary form must reproduce the above
+    copyright notice, this list of conditions and the following
+    disclaimer in the documentation and/or other materials provided with
+    the distribution.
+
+    (3)The name of the author may not be used to endorse or promote
+    products derived from this software without specific prior written
+    permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,43 @@
+Wires
+=====
+
+This is a functional reactive programming library for interactive
+applications with the following features:
+
+  * heavy focus on real-time applications like games and simulations,
+
+  * very small core abstraction,
+
+  * efficient in both time and space.
+
+Until a proper tutorial has been written, please check out the
+*examples* directory.  If you have questions, join #haskell-game on
+irc.freenode.net.  If you would like to report a bug or request a
+feature, please [file an
+issue](https://github.com/esoeylemez/wires/issues).
+
+
+Module overview
+---------------
+
+The library is split into two roles: *applications* and *controllers*.
+An application developer models interactions and implements reactive
+systems, i.e. the application logic.  A controller developer implements
+the glue between the application and the real world, i.e. how events and
+time-varying values map to actual things on the screen or in the
+network.  The module structure reflects that distinction:
+
+Module                    | Purpose
+--------------------------|-----------------------------------------------
+`Control.Wire`            | Application language (basically core + utils).
+`Control.Wire.Controller` | Controller language.
+`Control.Wire.Core`       | Core application language.
+`Control.Wire.Internal`   | You should never need this module.
+`Control.Wire.Utils`      | Extra application utilities.
+
+Modules not listed here are highly experimental and should not be used.
+
+If you are asking yourself whether you are an application or a
+controller developer: at this early stage of development you are
+probably both, which means that you will write the application as well
+as connect its inputs and outputs to the real world.
diff --git a/Setup.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,6 @@
+> module Main (main) where
+>
+> import Distribution.Simple
+>
+> main :: IO ()
+> main = defaultMain
diff --git a/examples/Utils.hs b/examples/Utils.hs
new file mode 100644
--- /dev/null
+++ b/examples/Utils.hs
@@ -0,0 +1,29 @@
+-- |
+-- Copyright:  (c) 2016 Ertugrul Söylemez
+-- License:    BSD3
+-- Maintainer: Ertugrul Söylemez <esz@posteo.de>
+-- Stability:  experimental
+
+module Utils
+    ( -- * Utilities
+      average
+    )
+    where
+
+import Control.Wire
+import Data.Foldable
+import Data.Profunctor
+import qualified Data.Sequence as Seq
+
+
+-- | Average of the given event's payload over the last given number of
+-- occurrences.
+
+average :: (Fractional a, Monad m) => Int -> Wire m (Event a) (Event a)
+average n =
+    lmap (fmap go) (unfoldE Seq.empty)
+    where
+    go x xs' =
+        let xs = Seq.take n (x Seq.<| xs')
+        in (foldl' (+) 0 xs / fromIntegral (Seq.length xs),
+            xs)
diff --git a/examples/ping-pong.hs b/examples/ping-pong.hs
new file mode 100644
--- /dev/null
+++ b/examples/ping-pong.hs
@@ -0,0 +1,71 @@
+-- |
+-- Copyright:  (c) 2016 Ertugrul Söylemez
+-- License:    BSD3
+-- Maintainer: Ertugrul Söylemez <esz@posteo.de>
+-- Stability:  experimental
+
+{-# LANGUAGE Arrows #-}
+
+module Main (main) where
+
+import Control.Monad.IO.Class
+import Control.Wire
+import Control.Wire.Controller
+import GHC.Stats
+import Prelude hiding ((.), id)
+import System.Clock
+import System.IO
+import System.Mem
+import Text.Printf
+import Utils
+
+
+newCharEvent :: (MonadIO m) => Wire m a (Event Char)
+newCharEvent = proc _ ->
+    newEvent -< liftIO $ do
+        b <- hReady stdin
+        if b then Just <$> getChar else pure Nothing
+
+
+newTickEvent :: (MonadIO m) => Wire m a (Event Double)
+newTickEvent = proc _ -> do
+    times <- newEvent -< Just <$> getT
+    withM_ unfoldE getT -< fmap (\t t' -> (secs (t - t'), t)) times
+
+    where
+    secs = (/ 1000000000) . fromInteger . toNanoSecs
+    getT = liftIO (getTime Monotonic)
+
+
+myApp :: (MonadIO m) => Wire m a (Event ())
+myApp = proc _ -> do
+    deltas <- newTickEvent -< ()
+    fps <- hold 0 . (fmap recip <$> average 25) -< deltas
+    chars <- newCharEvent -< ()
+
+    acc <- scan 1 -< negate <$ filterE (== ' ') chars
+    vel <- scan 0 -< fmap (\dt -> min 2 . max (-2) . (+ acc*dt)) deltas
+    pos <- scan 0 -< fmap (\dt -> min 1 . max (-1) . (+ vel*dt)) deltas
+
+    animate -< liftIO $ do
+        performGC
+        mem <- (`div` 1024) . currentBytesUsed <$> getGCStats
+        printf "\r%8dk %8.2f %5.2f %s %s\027[K"
+            mem
+            fps
+            vel
+            (if acc > 0 then ">" else "<")
+            (map (\xI ->
+                      let x = -1 + 2 * fromInteger xI / 59
+                      in if abs (pos - x) < 0.1 then 'X' else '.')
+                 [0..59])
+        hFlush stdout
+
+    id -< () <$ filterE (== 'q') chars
+
+
+main :: IO ()
+main = do
+    hSetBuffering stdin NoBuffering
+    hSetEcho stdin False
+    control myApp
diff --git a/wires.cabal b/wires.cabal
new file mode 100644
--- /dev/null
+++ b/wires.cabal
@@ -0,0 +1,61 @@
+name:     wires
+version:  0.1.0
+category: Control, FRP
+synopsis: Functional reactive programming library
+
+maintainer:   Ertugrul Söylemez <esz@posteo.de>
+author:       Ertugrul Söylemez <esz@posteo.de>
+copyright:    Copyright 2016 Ertugrul Söylemez
+homepage:     https://github.com/esoeylemez/wires
+bug-reports:  https://github.com/esoeylemez/wires/issues
+license:      BSD3
+license-file: LICENSE
+
+description:  Functional reactive programming library.
+
+build-type:         Simple
+cabal-version:      >= 1.10
+extra-source-files: CHANGELOG.md README.md
+
+source-repository head
+    type:     git
+    location: https://github.com/esoeylemez/wires.git
+
+flag Examples
+    default: False
+    description: Build the example programs
+    manual: True
+
+
+library
+    build-depends:
+        base                >= 4.8 && < 5,
+        deepseq             >= 1.4 && < 2,
+        profunctors         >= 5.2 && < 6,
+        semigroupoids       >= 5.1 && < 6,
+        these               >= 0.7 && < 1
+    default-language: Haskell2010
+    ghc-options: -W -fdefer-typed-holes
+    exposed-modules:
+        Control.Wire
+        Control.Wire.Controller
+        Control.Wire.Core
+        Control.Wire.Internal
+        Control.Wire.Utils
+        Control.Wire.Varying
+
+executable wires-ping-pong
+    if flag(examples)
+        build-depends:
+            base >= 4.8 && < 5,
+            clock,
+            containers,
+            profunctors,
+            wires
+    else
+        buildable: False
+    default-language: Haskell2010
+    ghc-options: -threaded -fdefer-typed-holes
+    hs-source-dirs: examples
+    main-is: ping-pong.hs
+    other-modules: Utils
