diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+NanoID, lib & app, Copyright (c) 2021, Michel Boucey
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * 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.
+
+    * Neither the name of Michel Boucey nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"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 COPYRIGHT
+OWNER OR CONTRIBUTORS 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/NanoID.cabal b/NanoID.cabal
new file mode 100644
--- /dev/null
+++ b/NanoID.cabal
@@ -0,0 +1,39 @@
+name:                NanoID
+version:             1.0.0
+synopsis:            NanoID generator
+description:         Library and CLI tool for NanoID generation
+license:             BSD3
+license-file:        LICENSE
+author:              Michel Boucey
+maintainer:          michel.boucey@gmail.com
+copyright:           (c) 2021 - Michel Boucey
+category:            Data
+build-type:          Simple
+cabal-version:       >=1.10
+
+Tested-With: GHC ==8.4.4 || ==8.6.5 || ==8.8.4 || ==8.10.1 || ==8.10.4 || ==9.0.1
+
+source-repository head
+  type:     git
+  location: git://github.com/MichelBoucey/NanoID.git
+
+library
+  exposed-modules:     Data.NanoID
+  build-depends:       base >=4.7 && <4.15
+                     , bytestring >= 0.10 && < 0.12
+                     , extra >= 1.6 && < 1.8
+                     , mwc-random >= 0.13 && < 0.16
+  hs-source-dirs:      src
+  default-language:    Haskell2010
+
+executable nanoid
+  main-is:             Main.hs
+  other-modules:       Options
+  build-depends:       base >=4.7 && <4.15
+                     , bytestring >= 0.10 && < 0.12
+                     , mwc-random >= 0.13 && < 0.16
+                     , NanoID
+                     , optparse-applicative >= 0.14 && < 0.17
+  hs-source-dirs:      app
+  default-language:    Haskell2010
+
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/app/Main.hs b/app/Main.hs
new file mode 100644
--- /dev/null
+++ b/app/Main.hs
@@ -0,0 +1,24 @@
+{-# LANGUAGE RecordWildCards #-}
+
+import           Control.Monad
+import qualified Data.ByteString.Char8 as C
+import           Options.Applicative
+import           System.Exit
+import           System.Random.MWC
+
+import           Data.NanoID
+import           Options
+
+main :: IO ()
+main = do
+  Options{..} <- execParser opts
+  if length > 21
+    then putStrLn "The length of NanoID is less or equal to 21" >> exitFailure
+    else do
+      let alphabet' = Alphabet { unAlphabet = C.pack alphabet }
+      replicateM_ quantity $
+        unNanoID <$> (createSystemRandom >>= customNanoID alphabet' length) >>= putNanoID newline
+      exitSuccess
+      where
+        putNanoID n = if n then C.putStrLn else C.putStr
+
diff --git a/app/Options.hs b/app/Options.hs
new file mode 100644
--- /dev/null
+++ b/app/Options.hs
@@ -0,0 +1,47 @@
+module Options where
+
+import qualified Data.ByteString.Char8 as C
+import           Data.NanoID
+import           Options.Applicative
+
+data Options =
+  Options
+    { alphabet :: String
+    , length   :: Int
+    , quantity :: Int
+    , newline  :: Bool
+    }
+
+opts :: ParserInfo Options
+opts = info (options <**> helper)
+  ( fullDesc
+    <> progDesc "NanoID generator"
+    <> header "nanoid v1.0.0, (c) Michel Boucey 2021" )
+
+options :: Parser Options
+options =
+  Options
+    <$>
+      strOption
+        ( short 'a'
+          <> long "alphabet"
+          <> help "Use an alternative alphabet (ascii chars only)"
+          <> value (C.unpack $ unAlphabet defaultAlphabet) )
+    <*>
+      option auto
+        ( short 'l'
+          <> long "length"
+          <> help "Get shorter NanoID"
+          <> value 21 )
+    <*>
+      option auto
+        ( short 'q'
+          <> long "quantity"
+          <> help "Quantity of NanoID to generate"
+          <> value 1 )
+    <*>
+      flag True False
+        ( short 'n'
+          <> long "newline"
+          <> help "Do not output the trailing newline" )
+
diff --git a/src/Data/NanoID.hs b/src/Data/NanoID.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/NanoID.hs
@@ -0,0 +1,24 @@
+module Data.NanoID where
+
+import           Control.Monad
+import qualified Data.ByteString.Char8 as C
+import           System.Random.MWC
+
+newtype NanoID = NanoID { unNanoID :: C.ByteString } deriving (Eq, Show)
+
+newtype Alphabet = Alphabet { unAlphabet :: C.ByteString } deriving (Eq, Show)
+
+type Length = Int
+
+defaultAlphabet :: Alphabet
+defaultAlphabet = Alphabet (C.pack "ABCDEFGHIJKLMNOPKRSTUVWXYZ_-abcdefghijklmnopqrstuvwxyz")
+
+nanoID :: IO NanoID
+nanoID = createSystemRandom >>= customNanoID defaultAlphabet 21
+
+customNanoID :: Alphabet -> Length -> GenIO-> IO NanoID
+customNanoID a l g = do
+  let acs = unAlphabet a
+      al = C.length acs
+  NanoID . C.pack <$> replicateM l ((\r -> C.index acs (r-1)) <$> uniformR (1,al) g)
+
