diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,12 @@
+# Changelog
+
+`non` uses [PVP Versioning][1].
+The changelog is available [on GitHub][2].
+
+0.1
+===
+
+* Initially created.
+
+[1]: https://pvp.haskell.org
+[2]: https://github.com/chessai/non-empty-applicative/releases
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2019 chessai
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,7 @@
+# non-empty-applicative
+
+[![Hackage](https://img.shields.io/hackage/v/non-empty-applicative.svg)](https://hackage.haskell.org/package/non-empty-applicative)
+[![MIT license](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
+[![Build status](https://secure.travis-ci.org/chessai/non-empty-applicative.svg)](https://travis-ci.org/chessai/non-empty-applicative)
+
+non-empty applicative structure
diff --git a/nonempty-lift.cabal b/nonempty-lift.cabal
new file mode 100644
--- /dev/null
+++ b/nonempty-lift.cabal
@@ -0,0 +1,68 @@
+cabal-version: 2.2
+name:
+  nonempty-lift
+version:
+  0.1
+synopsis:
+  nonempty structure
+description:
+  nonempty structure, parameterised by another structure
+homepage:
+  https://github.com/chessai/nonempty
+bug-reports:
+  https://github.com/chessai/nonempty/issues
+license:
+  BSD-3-Clause
+license-file:
+  LICENSE
+author:
+  chessai
+maintainer:
+  chessai <chessai1996@gmail.com>
+copyright:
+  © 2019 chessai
+category:
+  Data
+build-type:
+  Simple
+extra-doc-files:
+    README.md
+  , CHANGELOG.md
+tested-with:
+  GHC == 8.6.5
+
+library
+  hs-source-dirs:
+    src
+  exposed-modules:
+    NonEmpty
+  build-depends:
+    , base >= 4.12 && < 4.13
+    , comonad >= 5 && < 5.1
+    , semigroupoids >= 5.3 && < 5.4
+  ghc-options:
+    -Wall
+    -O2
+  default-language:
+    Haskell2010
+
+test-suite laws
+  type:
+    exitcode-stdio-1.0
+  hs-source-dirs:
+    test
+  main-is:
+    Laws.hs
+  build-depends:
+    , base
+    , hedgehog
+    , hedgehog-classes >= 0.2.3 && < 0.3
+    , nonempty-lift
+  default-language:
+    Haskell2010
+
+source-repository head
+  type:
+    git
+  location:
+    https://github.com/chessai/nonempty.git
diff --git a/src/NonEmpty.hs b/src/NonEmpty.hs
new file mode 100644
--- /dev/null
+++ b/src/NonEmpty.hs
@@ -0,0 +1,149 @@
+{-# language
+        DeriveAnyClass
+      , DeriveFoldable
+      , DeriveFunctor
+      , DeriveGeneric
+      , DeriveTraversable
+      , DerivingStrategies
+  #-}
+
+{-| This module provides a way to lift potentially empty structures
+    into one which is guaranteed to be NonEmpty by construction.
+-}
+
+module NonEmpty
+  ( NonEmpty(..)
+
+  , head
+  , tail
+  , toList
+  , zip
+  , zipWith
+  , unzip
+  , nonEmpty
+  ) where
+
+import Control.Comonad
+import Control.Comonad.Hoist.Class
+import Control.Monad.Zip
+import Data.Foldable hiding (toList)
+import Data.Functor.Apply
+import Data.Semigroup.Foldable.Class
+import GHC.Generics (Generic, Generic1)
+import Prelude hiding (head, tail,zip,zipWith,unzip)
+import qualified Data.Foldable as F
+import qualified Data.List.NonEmpty as NE
+
+-- | A structure which is nonempty by construction.
+--
+--   Typically this will be used to construct list-like structures; e.g.
+--
+--   * @NonEmpty [] a@ is a lazy list containing at least one element.
+--
+--   * @NonEmpty (NonEmpty []) a@ is a lazy list containing at least two
+--   elements.
+--
+--   * @NonEmpty Maybe a@ is a list that contains one or two elements.
+data NonEmpty f a = NonEmpty a (f a)
+  deriving stock (Functor, Foldable, Traversable)
+  deriving stock (Generic, Generic1)
+  deriving stock (Show, Read)
+  deriving stock (Eq, Ord)
+  deriving anyclass (ComonadApply)
+
+instance Applicative f => Applicative (NonEmpty f) where
+  pure x = NonEmpty x (pure x)
+  (<*>) = apNonEmpty (<*>)
+
+instance Apply f => Apply (NonEmpty f) where
+  (<.>) = apNonEmpty (<.>)
+
+apNonEmpty :: ()
+  => (f (a -> b) -> f a -> f b)
+  -> NonEmpty f (a -> b)
+  -> NonEmpty f a
+  -> NonEmpty f b
+apNonEmpty ap (NonEmpty f fs) (NonEmpty x xs) = NonEmpty (f x) (ap fs xs)
+{-# inline apNonEmpty #-}
+
+instance (Applicative f, Comonad f) => Comonad (NonEmpty f) where
+  extract = head
+  duplicate w@(NonEmpty _ f) = NonEmpty w (fmap pure f)
+
+instance ComonadHoist NonEmpty where
+  cohoist f (NonEmpty x w) = NonEmpty x (f w)
+
+-- i don't understand trace comonads yet, so i won't include this.
+--instance (Monoid m, ComonadTraced m w) => ComonadTraced m (NonEmpty w) where
+
+-- Is this lawful? What are the laws of ComonadTrans?
+-- Is it just dual to MonadTrans, i.e. 'lower' must be
+-- a Comonad homomorphism?
+--instance ComonadTrans NonEmpty where
+--  lower = tail
+
+instance (Foldable f) => Foldable1 (NonEmpty f) where
+  fold1 (NonEmpty a f) = fold' a f
+  {-# inline fold1 #-}
+  foldMap1 h (NonEmpty a f) = foldMap' a h f
+  {-# inline foldMap1 #-}
+  toNonEmpty (NonEmpty a f) = toNonEmpty' a f
+  {-# inline toNonEmpty #-}
+
+-- | Get the head of a 'NonEmpty'.
+head :: NonEmpty f a -> a
+head ~(NonEmpty a _) = a
+{-# inline head #-}
+
+-- | Get the 'tail' of a 'NonEmpty'.
+tail :: NonEmpty f a -> f a
+tail ~(NonEmpty _ f) = f
+{-# inline tail #-}
+
+-- | Convert a 'NonEmpty' into a list.
+toList :: Foldable f => NonEmpty f a -> [a]
+toList ~(NonEmpty a f) = a : F.toList f
+{-# inline toList #-}
+
+-- | Zip two 'NonEmpty's together.
+zip :: (MonadZip f)
+  => NonEmpty f a
+  -> NonEmpty f b
+  -> NonEmpty f (a,b)
+zip = zipWith (,)
+{-# inline zip #-}
+
+-- | Zip two 'NonEmpty's together with a combining function.
+zipWith :: (MonadZip f)
+  => (a -> b -> c)
+  -> NonEmpty f a
+  -> NonEmpty f b
+  -> NonEmpty f c
+zipWith f ~(NonEmpty a fa) ~(NonEmpty b fb)
+  = NonEmpty (f a b) (mzipWith f fa fb)
+{-# inline zipWith #-}
+
+-- | Unzip a 'NonEmpty'.
+unzip :: (Functor f)
+  => NonEmpty f (a,b)
+  -> (NonEmpty f a, NonEmpty f b)
+unzip = NE.unzip
+{-# inline unzip #-}
+
+-- | Construct a 'NonEmpty'.
+nonEmpty :: a -> f a -> NonEmpty f a
+nonEmpty = NonEmpty
+{-# inline nonEmpty #-}
+
+-- Internal --
+toNonEmpty' :: (Foldable t) => a -> t a -> NE.NonEmpty a
+toNonEmpty' a xs = a NE.:| F.toList xs
+{-# inline toNonEmpty' #-}
+
+foldMap' :: (Semigroup m, Foldable t) => a -> (a -> m) -> t a -> m
+foldMap' z0 f = foldr ((<>) . f) (f z0)
+{-# inline foldMap' #-}
+
+fold' :: (Semigroup m, Foldable t) => m -> t m -> m
+fold' z0 = foldMap' z0 id
+{-# inline fold' #-}
diff --git a/test/Laws.hs b/test/Laws.hs
new file mode 100644
--- /dev/null
+++ b/test/Laws.hs
@@ -0,0 +1,41 @@
+module Main (main) where
+
+import Control.Applicative (liftA2)
+import Hedgehog
+import Hedgehog.Classes
+import NonEmpty
+import qualified Data.List.NonEmpty as Base
+import qualified Hedgehog.Gen as Gen
+import qualified Hedgehog.Range as Range
+
+main :: IO Bool
+main = lawsCheckMany
+  [ ( "NonEmpty f"
+    , [ functorLaws genNonEmpty1
+      , foldableLaws genNonEmpty1
+      , applicativeLaws genNonEmpty1
+      , traversableLaws genNonEmpty1
+      , comonadLaws genNonEmpty1
+      ]
+    )
+  , ( "NonEmpty f a"
+    , [ showLaws genNonEmpty
+      , showReadLaws genNonEmpty
+      , eqLaws genNonEmpty
+      , ordLaws genNonEmpty
+      -- , genericLaws genNonEmpty
+      ]
+    )
+  ]
+
+genNonEmpty :: Gen (NonEmpty Base.NonEmpty [Integer])
+genNonEmpty = genNonEmpty1 (Gen.list (Range.linear 0 6) genInteger)
+
+genInteger :: Gen Integer
+genInteger = Gen.integral_ (Range.linear (-1000) 1000)
+
+genNonEmpty1 :: Gen a -> Gen (NonEmpty Base.NonEmpty a)
+genNonEmpty1 gen = do
+  a <- gen
+  as <- liftA2 (Base.:|) gen (Gen.list (Range.linear 0 6) gen)
+  pure (NonEmpty a as)
