diff --git a/lib/file_system.ex b/lib/file_system.ex
index c520e48cbe3d3e91086f24ef2fa311a677297755..419ad230f72d589eae26d1e11051db46ab4dc374 100644
--- a/lib/file_system.ex
+++ b/lib/file_system.ex
@@ -1,15 +1,51 @@
 defmodule FileSystem do
-  defmacro __using__(options) do
-    quote do
-      @file_system_module_options unquote(options)
-      @before_compile FileSystem.ModuleApi
-    end
-  end
+  @moduledoc File.read!("README.md")
+
+  @doc """
+  ## Options
+
+    * `:dirs` ([string], requires), the dir list to monitor
+
+    * `:backend` (atom, optional), default backends: `:fs_mac`
+      for `macos`, `:fs_inotify` for `linux` and `freebsd`,
+      `:fs_windows` for `windows`
+
+    * `:listener_extra_args` (string, optional), extra args for
+      port backend.
+
+    * `:name` (atom, optional), `name` can be used to subscribe as
+      the same as pid when the `name` is given. The `name` should
+      be the name of worker process.
+
+  ## Example
 
-  def start_link(args) do
-    FileSystem.Worker.start_link(args)
+  Simple usage:
+
+      iex> {:ok, pid} = FileSystem.start_link(dirs: ["/tmp/fs"])
+      iex> FileSystem.subscribe(pid)
+
+  Get nstant notifications on file changes for Mac OS X:
+
+      iex> FileSystem.start_link(dirs: ["/path/to/some/files"], listener_extra_args: "--latency=0.0")
+
+  Named monitir with specialty backend:
+
+      iex> FileSystem.start_link(backend: :fs_mac, dirs: ["/tmp/fs"], name: :worker)
+      iex> FileSystem.subscribe(:worker)
+  """
+  @spec start_link(Keyword.t) :: {:ok, pid}
+  def start_link(options) do
+    FileSystem.Worker.start_link(options)
   end
 
+  @doc """
+  Regester current process as a subscriber of file_system worker.
+  The pid you subscribed from will now receive messages like
+
+      {:file_event, worker_pid, {file_path, events}}
+      {:file_event, worker_pid, :stop}
+  """
+  @spec subscribe(pid() | atom()) :: :ok
   def subscribe(pid) do
     GenServer.call(pid, :subscribe)
   end
diff --git a/lib/file_system/backend.ex b/lib/file_system/backend.ex
index 14204d4cf206377b8d344654102112048e13550b..293a09b6d34965dfd1cba6f64be5080e38d7f46c 100644
--- a/lib/file_system/backend.ex
+++ b/lib/file_system/backend.ex
@@ -1,10 +1,22 @@
 require Logger
 
 defmodule FileSystem.Backend do
+  @moduledoc """
+  FileSystem Backend Behaviour.
+  """
+
   @callback bootstrap() :: :ok | {:error, atom()}
   @callback supported_systems() :: [{atom(), atom()}]
   @callback known_events() :: [atom()]
 
+  @doc """
+  Get and validate backend module, return `{:ok, backend_module}` when success and
+  return `{:error, reason}` when fail.
+  When `nil` is given, will return default backend by os.
+  When a custom module is given, make sure `start_link/1`, `bootstrap/0` and
+  `supported_system/0` are defnied.
+  """
+  @spec backend(:atom) :: {:ok, atom()} | {:error, atom()}
   def backend(backend) do
     with {:ok, module} <- backend_module(backend),
          :ok <- validate_os(backend, module),
diff --git a/lib/file_system/backends/fs_inotify.ex b/lib/file_system/backends/fs_inotify.ex
index a57c64ac641388b5f7372503bc9790500d50a317..ba518bb4587145664f35fbe4c305925a6b77e4d0 100644
--- a/lib/file_system/backends/fs_inotify.ex
+++ b/lib/file_system/backends/fs_inotify.ex
@@ -2,6 +2,13 @@ require Logger
 alias FileSystem.Utils
 
 defmodule FileSystem.Backends.FSInotify do
+  @moduledoc """
+  This file is a fork from https://github.com/synrc/fs.
+  FileSysetm backend for linux and freebsd, a GenServer receive data from Port, parse event
+  and send it to the worker process.
+  Need `inotify-tools` installed to use this backend.
+  """
+
   use GenServer
   @behaviour FileSystem.Backend
   @sep_char <<1>>
@@ -24,7 +31,7 @@ defmodule FileSystem.Backends.FSInotify do
     [:created, :deleted, :renamed, :closed, :modified, :isdir, :attribute, :undefined]
   end
 
-  def find_executable do
+  defp find_executable do
     System.find_executable("inotifywait")
   end
 
diff --git a/lib/file_system/backends/fs_mac.ex b/lib/file_system/backends/fs_mac.ex
index aea5429fa584e1f8b6e90e1388e1605290cb34fe..d56c6932def14ad646336a0bf205b0a514a4ff26 100644
--- a/lib/file_system/backends/fs_mac.ex
+++ b/lib/file_system/backends/fs_mac.ex
@@ -2,6 +2,13 @@ require Logger
 alias FileSystem.Utils
 
 defmodule FileSystem.Backends.FSMac do
+  @moduledoc """
+  This file is a fork from https://github.com/synrc/fs.
+  FileSysetm backend for macos, a GenServer receive data from Port, parse event
+  and send it to the worker process.
+  will compile executable the buildin executable file when file the first time it is used.
+  """
+
   use GenServer
   @behaviour FileSystem.Backend
 
@@ -33,10 +40,11 @@ defmodule FileSystem.Backends.FSMac do
     ]
   end
 
-  def find_executable do
+  defp find_executable do
     (:code.priv_dir(:file_system) ++ '/mac_listener') |> to_string
   end
 
+
   def start_link(args) do
     GenServer.start_link(__MODULE__, args, [])
   end
diff --git a/lib/file_system/backends/fs_windows.ex b/lib/file_system/backends/fs_windows.ex
index 9f194f3d9435a6e49e1e0ebecff0ee78e118d5ba..5027be3da8483f6c4feac63325fdfaea933a1515 100644
--- a/lib/file_system/backends/fs_windows.ex
+++ b/lib/file_system/backends/fs_windows.ex
@@ -2,6 +2,13 @@ require Logger
 alias FileSystem.Utils
 
 defmodule FileSystem.Backends.FSWindows do
+  @moduledoc """
+  This file is a fork from https://github.com/synrc/fs.
+  FileSysetm backend for windows, a GenServer receive data from Port, parse event
+  and send it to the worker process.
+  Need binary executable file packaged in to use this backend.
+  """
+
   use GenServer
   @behaviour FileSystem.Backend
   @sep_char <<1>>
@@ -24,7 +31,7 @@ defmodule FileSystem.Backends.FSWindows do
     [:created, :modified, :removed, :renamed, :undefined]
   end
 
-  def find_executable do
+  defp find_executable do
     (:code.priv_dir(:file_system) ++ '/inotifywait.exe') |> to_string
   end
 
diff --git a/lib/file_system/utils.ex b/lib/file_system/utils.ex
index b24eeb9a337e1d8374c42e32f83d5d58bf96306b..f87c900381d34030033a1a4ff06f650ce155df15 100644
--- a/lib/file_system/utils.ex
+++ b/lib/file_system/utils.ex
@@ -1,14 +1,19 @@
 defmodule FileSystem.Utils do
+  @moduledoc false
+
+  @doc false
+  @spec format_path(String.t() | [String.t()]) :: [charlist()]
   def format_path(path) when is_list(path) do
     for i <- path do
       i |> Path.absname |> to_charlist
     end
   end
-
   def format_path(path) do
     [path] |> format_path
   end
 
+  @doc false
+  @spec format_args(nil | String.t() | [String.t()]) :: [charlist()]
   def format_args(nil), do: []
   def format_args(str) when is_binary(str) do
     str |> String.split |> format_args
diff --git a/lib/file_system/worker.ex b/lib/file_system/worker.ex
index b66fa9474cdf7762755c5a11dea5bed9b2938daa..fbdee6bbbee51262363e5530c021b83aed2a6415 100644
--- a/lib/file_system/worker.ex
+++ b/lib/file_system/worker.ex
@@ -1,11 +1,18 @@
 defmodule FileSystem.Worker do
+  @moduledoc """
+  FileSystem Worker Process with the backend GenServer, receive events from Port Process
+  and forward it to subscribers.
+  """
+
   use GenServer
 
+  @doc false
   def start_link(args) do
     {args, opts} = Keyword.split(args, [:backend, :dirs, :listener_extra_args])
     GenServer.start_link(__MODULE__, args, opts)
   end
 
+  @doc false
   def init(args) do
     case FileSystem.Backend.backend(args[:backend]) do
       {:ok, backend} ->
@@ -16,12 +23,14 @@ defmodule FileSystem.Worker do
     end
   end
 
+  @doc false
   def handle_call(:subscribe, {pid, _}, state) do
     ref = Process.monitor(pid)
     state = put_in(state, [:subscribers, ref], pid)
     {:reply, :ok, state}
   end
 
+  @doc false
   def handle_info({:backend_file_event, backend_pid, file_event}, %{backend_pid: backend_pid}=state) do
     state.subscribers |> Enum.each(fn {_ref, subscriber_pid} ->
       send(subscriber_pid, {:file_event, self(), file_event})