diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,7 @@
+2023-08-21 Ivan Perez <ivan.perez@keera.co.uk>
+        * Version bump (0.14.4) (#377).
+        * Offer all definitions from FRP.Yampa.Basic (#376).
+
 2023-06-21 Ivan Perez <ivan.perez@keera.co.uk>
         * Version bump (0.14.3) (#372).
         * Offer all definitions from FRP.Yampa.Arrow (#360).
diff --git a/bearriver.cabal b/bearriver.cabal
--- a/bearriver.cabal
+++ b/bearriver.cabal
@@ -30,7 +30,7 @@
 build-type:    Simple
 
 name:          bearriver
-version:       0.14.3
+version:       0.14.4
 author:        Ivan Perez, Manuel Bärenz
 maintainer:    ivan.perez@keera.co.uk
 homepage:      https://github.com/ivanperez-keera/dunai
@@ -77,7 +77,11 @@
   exposed-modules:
     FRP.BearRiver
     FRP.BearRiver.Arrow
+    FRP.BearRiver.Basic
     FRP.Yampa
+
+  other-modules:
+    FRP.BearRiver.InternalCore
 
   build-depends:
       base >= 4.6 && <5
diff --git a/src/FRP/BearRiver.hs b/src/FRP/BearRiver.hs
--- a/src/FRP/BearRiver.hs
+++ b/src/FRP/BearRiver.hs
@@ -26,7 +26,6 @@
 #endif
 import           Control.Applicative       (Alternative (..))
 import           Control.Arrow             as X
-import qualified Control.Category          as Category
 import           Control.DeepSeq           (NFData (..))
 import qualified Control.Monad.Fail        as Fail
 import           Control.Monad.Random      (MonadRandom)
@@ -47,36 +46,16 @@
                                                                trace)
 import           Data.MonadicStreamFunction.InternalCore (MSF (MSF, unMSF))
 import           FRP.BearRiver.Arrow                     as X
+import           FRP.BearRiver.Basic                     as X
+import           FRP.BearRiver.InternalCore              as X
 
 -- Internal imports (dunai, instances)
 import Data.MonadicStreamFunction.Instances.ArrowLoop () -- not needed, just
                                                          -- re-exported
-
-infixr 0 -->, -:>, >--, >=-
+                                                         --
 
 -- * Basic definitions
 
--- | Time is used both for time intervals (duration), and time w.r.t. some
--- agreed reference point in time.
-type Time = Double
-
--- | DTime is the time type for lengths of sample intervals. Conceptually,
--- DTime = R+ = { x in R | x > 0 }. Don't assume Time and DTime have the same
--- representation.
-type DTime = Double
-
--- | Extensible signal function (signal function with a notion of time, but
--- which can be extended with actions).
---
--- Signal function that transforms a signal carrying values of some type 'a'
--- into a signal carrying values of some type 'b'. You can think of it as
--- (Signal a -> Signal b). A signal is, conceptually, a function from 'Time' to
--- value.
-type SF m = MSF (ClockInfo m)
-
--- | Information on the progress of time.
-type ClockInfo m = ReaderT DTime m
-
 -- | A single possible event occurrence, that is, a value that may or may not
 -- occur. Events are used to represent values that are not produced
 -- continuously, such as mouse clicks (only produced when the mouse is clicked,
@@ -144,22 +123,6 @@
 
 -- ** Basic signal functions
 
--- | Identity: identity = arr id
---
--- Using 'identity' is preferred over lifting id, since the arrow combinators
--- know how to optimise certain networks based on the transformations being
--- applied.
-identity :: Monad m => SF m a a
-identity = Category.id
-
--- | Identity: constant b = arr (const b)
---
--- Using 'constant' is preferred over lifting const, since the arrow
--- combinators know how to optimise certain networks based on the
--- transformations being applied.
-constant :: Monad m => b -> SF m a b
-constant = arr . const
-
 -- | Outputs the time passed since the signal function instance was started.
 localTime :: Monad m => SF m a Time
 localTime = constant 1.0 >>> integral
@@ -168,41 +131,7 @@
 time :: Monad m => SF m a Time
 time = localTime
 
--- ** Initialization
 
--- | Initialization operator (cf. Lustre/Lucid Synchrone).
---
--- The output at time zero is the first argument, and from that point on it
--- behaves like the signal function passed as second argument.
-(-->) :: Monad m => b -> SF m a b -> SF m a b
-b0 --> sf = sf >>> replaceOnce b0
-
--- | Output pre-insert operator.
---
--- Insert a sample in the output, and from that point on, behave like the given
--- sf.
-(-:>) :: Monad m => b -> SF m a b -> SF m a b
-b -:> sf = iPost b sf
-
--- | Input initialization operator.
---
--- The input at time zero is the first argument, and from that point on it
--- behaves like the signal function passed as second argument.
-(>--) :: Monad m => a -> SF m a b -> SF m a b
-a0 >-- sf = replaceOnce a0 >>> sf
-
--- | Transform initial input value.
---
--- Applies a transformation 'f' only to the first input value at time zero.
-(>=-) :: Monad m => (a -> a) -> SF m a b -> SF m a b
-f >=- sf = MSF $ \a -> do
-  (b, sf') <- unMSF sf (f a)
-  return (b, sf')
-
--- | Override initial value of input signal.
-initially :: Monad m => a -> SF m a a
-initially = (--> identity)
-
 -- * Simple, stateful signal processing
 
 -- | Applies a function point-wise, using the last output as next input. This
@@ -878,12 +807,3 @@
 -- discrete and step based.
 evalFuture :: SF Identity a b -> a -> DTime -> (b, SF Identity a b)
 evalFuture sf = flip (evalAt sf)
-
--- * Auxiliary functions
-
--- ** Event handling
-
--- | Replace the value of the input signal at time zero with the given
--- argument.
-replaceOnce :: Monad m => a -> SF m a a
-replaceOnce a = dSwitch (arr $ const (a, Event ())) (const $ arr id)
diff --git a/src/FRP/BearRiver/Basic.hs b/src/FRP/BearRiver/Basic.hs
new file mode 100644
--- /dev/null
+++ b/src/FRP/BearRiver/Basic.hs
@@ -0,0 +1,109 @@
+-- |
+-- Module      : FRP.BearRiver.Basic
+-- Copyright   : (c) Ivan Perez, 2014-2022
+--               (c) George Giorgidze, 2007-2012
+--               (c) Henrik Nilsson, 2005-2006
+--               (c) Antony Courtney and Henrik Nilsson, Yale University, 2003-2004
+-- License     : BSD-style (see the LICENSE file in the distribution)
+--
+-- Maintainer  : ivan.perez@keera.co.uk
+-- Stability   : provisional
+-- Portability : non-portable (GHC extensions)
+--
+-- Defines basic signal functions, and elementary ways of altering them.
+--
+-- This module defines very basic ways of creating and modifying signal
+-- functions. In particular, it defines ways of creating constant output
+-- producing SFs, and SFs that just pass the signal through unmodified.
+--
+-- It also defines ways of altering the input and the output signal only by
+-- inserting one value in the signal, or by transforming it.
+module FRP.BearRiver.Basic
+    (
+      -- * Basic signal functions
+      identity
+    , constant
+
+      -- ** Initialization
+    , (-->)
+    , (-:>)
+    , (>--)
+    , (-=>)
+    , (>=-)
+    , initially
+    )
+  where
+
+-- External imports
+import qualified Control.Category as Category
+
+-- Internal imports (dunai)
+import Data.MonadicStreamFunction.InternalCore (MSF (MSF, unMSF))
+
+-- Internal imports
+import FRP.BearRiver.InternalCore (SF, arr)
+
+infixr 0 -->, -:>, >--, -=>, >=-
+
+-- * Basic signal functions
+
+-- | Identity: identity = arr id
+--
+-- Using 'identity' is preferred over lifting id, since the arrow combinators
+-- know how to optimise certain networks based on the transformations being
+-- applied.
+identity :: Monad m => SF m a a
+identity = Category.id
+
+-- | Identity: constant b = arr (const b)
+--
+-- Using 'constant' is preferred over lifting const, since the arrow combinators
+-- know how to optimise certain networks based on the transformations being
+-- applied.
+constant :: Monad m => b -> SF m a b
+constant = arr . const
+
+-- * Initialization
+
+-- | Initialization operator (cf. Lustre/Lucid Synchrone).
+--
+-- The output at time zero is the first argument, and from that point on it
+-- behaves like the signal function passed as second argument.
+(-->) :: Monad m => b -> SF m a b -> SF m a b
+b0 --> sf = MSF $ \a -> do
+  (_b, sf') <- unMSF sf a
+  return (b0, sf')
+
+-- | Output pre-insert operator.
+--
+-- Insert a sample in the output, and from that point on, behave like the given
+-- sf.
+(-:>) :: Monad m => b -> SF m a b -> SF m a b
+b -:> sf = MSF $ \_a -> return (b, sf)
+
+-- | Input initialization operator.
+--
+-- The input at time zero is the first argument, and from that point on it
+-- behaves like the signal function passed as second argument.
+(>--) :: Monad m => a -> SF m a b -> SF m a b
+a0 >-- sf = MSF $ \_ -> unMSF sf a0
+
+-- | Transform initial output value.
+--
+-- Applies a transformation 'f' only to the first output value at time zero.
+(-=>) :: Monad m => (b -> b) -> SF m a b -> SF m a b
+f -=> sf = MSF $ \a -> do
+  (b, sf') <- unMSF sf a
+  return (f b, sf')
+
+-- | Transform initial input value.
+--
+-- Applies a transformation 'f' only to the first input value at time zero.
+(>=-) :: Monad m => (a -> a) -> SF m a b -> SF m a b
+f >=- sf = MSF $ \a -> do
+  (b, sf') <- unMSF sf (f a)
+  return (b, sf')
+
+-- | Override initial value of input signal.
+initially :: Monad m => a -> SF m a a
+initially = (--> identity)
diff --git a/src/FRP/BearRiver/InternalCore.hs b/src/FRP/BearRiver/InternalCore.hs
new file mode 100644
--- /dev/null
+++ b/src/FRP/BearRiver/InternalCore.hs
@@ -0,0 +1,62 @@
+-- |
+-- Module      : FRP.Dunai.InternalCore
+-- Copyright   : (c) Ivan Perez, 2014-2022
+--               (c) George Giorgidze, 2007-2012
+--               (c) Henrik Nilsson, 2005-2006
+--               (c) Antony Courtney and Henrik Nilsson, Yale University, 2003-2004
+-- License     : BSD-style (see the LICENSE file in the distribution)
+--
+-- Maintainer  : ivan.perez@keera.co.uk
+-- Stability   : provisional
+-- Portability : non-portable (GHC extensions)
+--
+-- Domain-specific language embedded in Haskell for programming hybrid (mixed
+-- discrete-time and continuous-time) systems, extended with Monads.
+--
+-- Bearriver (a tributary to the Yampa river) provides the same API as Yampa,
+-- but implemented using Monadic Stream Functions underneath. SFs in BearRiver
+-- take an additional monad as argument. The introduction of time is done by
+-- means of an additional Reader layer.
+module FRP.BearRiver.InternalCore
+    ( module Control.Arrow
+
+      -- * Basic definitions
+      -- ** Time
+    , Time
+    , DTime
+
+      -- ** Signal Functions
+    , SF
+    , ClockInfo
+    )
+  where
+
+-- External imports
+import Control.Arrow (Arrow (..), ArrowChoice (..), ArrowLoop (..), (>>>))
+
+-- Internal imports (dunai)
+import Control.Monad.Trans.MSF    (ReaderT)
+import Data.MonadicStreamFunction (MSF)
+
+-- * Basic type definitions with associated utilities
+
+-- | Time is used both for time intervals (duration), and time w.r.t. some
+-- agreed reference point in time.
+type Time = Double
+
+-- | DTime is the time type for lengths of sample intervals. Conceptually,
+-- DTime = R+ = { x in R | x > 0 }. Don't assume Time and DTime have the same
+-- representation.
+type DTime = Double
+
+-- | Extensible signal function (signal function with a notion of time, but
+-- which can be extended with actions).
+--
+-- Signal function that transforms a signal carrying values of some type 'a'
+-- into a signal carrying values of some type 'b'. You can think of it as
+-- (Signal a -> Signal b). A signal is, conceptually, a function from 'Time' to
+-- value.
+type SF m = MSF (ClockInfo m)
+
+-- | Information on the progress of time.
+type ClockInfo m = ReaderT DTime m
