diff --git a/CHANGELOG.md b/CHANGELOG.md
index b594d5b4fbb093448061d1af5474b287d9169ffd..f4a678f7df8cbeb5963087c6359d5b5aa2ac2ac7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,13 @@ current (development)
 ---------------------
 
 ### DOM
+- Feature: Customize the cursor. Add the following decorators:
+  - `focusCursorBlock`
+  - `focusCursorBlockBlinking`
+  - `focusCursorBar`
+  - `focusCursorBarBlinking`
+  - `focusCursorUnderline`
+  - `focusCursorUnderlineBlinking`
 - Bugfix: Fix `focus`/`select` when the `vbox`/`hbox`/`dbox` contains a
   `flexbox`
 - Bugfix: Fix the selected/focused area. It used to be 1 cell larger/longer than
@@ -25,6 +32,7 @@ current (development)
   can be used to integrate FTXUI into another main loop, without taking the full
   control.
 - Feature: `Input` supports CTRL+Left and CTRL+Right
+- Feature: Use a blinking bar in the `Input` component.
 - Improvement: The `Menu` keeps the focus when an entry is selected with the
   mouse.
 - Bugfix: Add implementation of `ButtonOption::Border()`. It was missing.
diff --git a/examples/component/CMakeLists.txt b/examples/component/CMakeLists.txt
index 4eb971e68cb29e6861355115090540d64c7ac02e..5b618d2bc02378b881a31569a9ca7c2fb19ffe1a 100644
--- a/examples/component/CMakeLists.txt
+++ b/examples/component/CMakeLists.txt
@@ -13,6 +13,7 @@ example(custom_loop)
 example(dropdown)
 example(flexbox_gallery)
 example(focus)
+example(focus_cursor)
 example(gallery)
 example(homescreen)
 example(input)
diff --git a/examples/component/focus_cursor.cpp b/examples/component/focus_cursor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4bc6a1e15380bcb9464c36524e025a519188226d
--- /dev/null
+++ b/examples/component/focus_cursor.cpp
@@ -0,0 +1,39 @@
+#include <memory>  // for allocator, shared_ptr, __shared_ptr_access
+#include <string>  // for operator+, char_traits, to_string, string
+#include <vector>  // for vector
+
+#include "ftxui/component/component.hpp"       // for Slider, Renderer, Vertical
+#include "ftxui/component/screen_interactive.hpp"  // for ScreenInteractive
+#include "ftxui/dom/elements.hpp"  // for Elements, Element, operator|, separator, text, focusPositionRelative, size, border, flex, frame, bgcolor, gridbox, vbox, EQUAL, center, HEIGHT, WIDTH
+
+using namespace ftxui;
+
+Component Instance(std::string label, Decorator focusCursor) {
+  return Renderer([=](bool focused) {
+    if (focused) {
+      return hbox({
+          text("> " + label + " "),
+          focusCursor(text(" ")),
+      });
+    }
+    return text("  " + label + " ");
+  });
+};
+
+int main(int argc, const char* argv[]) {
+  auto screen = ScreenInteractive::Fullscreen();
+  screen.Loop(Container::Vertical({
+      Instance("focus", focus),
+      Instance("focusCursorBlock", focusCursorBlock),
+      Instance("focusCursorBlockBlinking", focusCursorBlockBlinking),
+      Instance("focusCursorBar", focusCursorBar),
+      Instance("focusCursorBarBlinking", focusCursorBarBlinking),
+      Instance("focusCursorUnderline", focusCursorUnderline),
+      Instance("focusCursorUnderlineBlinking", focusCursorUnderlineBlinking),
+  }));
+  return 0;
+}
+
+// Copyright 2020 Arthur Sonzogni. All rights reserved.
+// Use of this source code is governed by the MIT license that can be found in
+// the LICENSE file.
diff --git a/include/ftxui/dom/elements.hpp b/include/ftxui/dom/elements.hpp
index 4d690a447bb09fb4ab17f30667eae404f75c5c69..ce14801691454b93f33f5118b541be791fe9662f 100644
--- a/include/ftxui/dom/elements.hpp
+++ b/include/ftxui/dom/elements.hpp
@@ -126,9 +126,6 @@ enum Direction { WIDTH, HEIGHT };
 enum Constraint { LESS_THAN, EQUAL, GREATER_THAN };
 Decorator size(Direction, Constraint, int value);
 
-// --
-Decorator reflect(Box& box);
-
 // --- Frame ---
 // A frame is a scrollable area. The internal area is potentially larger than
 // the external one. The internal area is scrolled in order to make visible the
@@ -139,7 +136,21 @@ Element yframe(Element);
 Element focus(Element);
 Element select(Element);
 
+// --- Cursor ---
+// Those are similar to `focus`, but also change the shape of the cursor.
+Element focusCursorBlock(Element);
+Element focusCursorBlockBlinking(Element);
+Element focusCursorBar(Element);
+Element focusCursorBarBlinking(Element);
+Element focusCursorUnderline(Element);
+Element focusCursorUnderlineBlinking(Element);
+
+// --- Misc ---
 Element vscroll_indicator(Element);
+Decorator reflect(Box& box);
+// Before drawing the |element| clear the pixel below. This is useful in
+// combinaison with dbox.
+Element clear_under(Element element);
 
 // --- Util --------------------------------------------------------------------
 Element hcenter(Element);
@@ -148,10 +159,6 @@ Element center(Element);
 Element align_right(Element);
 Element nothing(Element element);
 
-// Before drawing the |element| clear the pixel below. This is useful in
-// combinaison with dbox.
-Element clear_under(Element element);
-
 namespace Dimension {
 Dimensions Fit(Element&);
 }  // namespace Dimension
diff --git a/include/ftxui/screen/screen.hpp b/include/ftxui/screen/screen.hpp
index 21eb377645b57d54554bb89743ca3b5e6e367cb5..4d15b956bd61798ef30d230179909eb9733baf5c 100644
--- a/include/ftxui/screen/screen.hpp
+++ b/include/ftxui/screen/screen.hpp
@@ -80,6 +80,17 @@ class Screen {
   struct Cursor {
     int x = 0;
     int y = 0;
+
+    enum Shape {
+      Hidden = 0,
+      BlockBlinking = 1,
+      Block = 2,
+      UnderlineBlinking = 3,
+      Underline = 4,
+      Bar = 5,
+      BarBlinking = 6,
+    };
+    Shape shape;
   };
   Cursor cursor() const { return cursor_; }
   void SetCursor(Cursor cursor) { cursor_ = cursor; }
@@ -91,8 +102,6 @@ class Screen {
   int dimy_;
   std::vector<std::vector<Pixel>> pixels_;
   Cursor cursor_;
-
- private:
 };
 
 }  // namespace ftxui
diff --git a/src/ftxui/component/input.cpp b/src/ftxui/component/input.cpp
index d56ce4be7c903eb08259e42846769df6092c6fac..66a4245e79ae3b99fd83bb9be831881ea180742f 100644
--- a/src/ftxui/component/input.cpp
+++ b/src/ftxui/component/input.cpp
@@ -96,24 +96,23 @@ class InputBase : public ComponentBase {
 
     // placeholder.
     if (size == 0) {
-      bool hovered = hovered_;
-      Decorator decorator = dim | main_decorator;
+      auto element = text(*placeholder_) | dim | main_decorator | reflect(box_);
       if (is_focused) {
-        decorator = decorator | focus;
+        element |= focus;
       }
-      if (hovered || is_focused) {
-        decorator = decorator | inverted;
+      if (hovered_|| is_focused) {
+        element |= inverted;
       }
-      return text(*placeholder_) | decorator | reflect(box_);
+      return element;
     }
 
     // Not focused.
     if (!is_focused) {
+      auto element = text(content) | main_decorator | reflect(box_);
       if (hovered_) {
-        return text(content) | main_decorator | inverted | reflect(box_);
-      } else {
-        return text(content) | main_decorator | reflect(box_);
-      }
+        element |= inverted;
+      } 
+      return element;
     }
 
     int index_before_cursor = GlyphPosition(content, cursor_position());
@@ -125,10 +124,10 @@ class InputBase : public ComponentBase {
                                       index_after_cursor - index_before_cursor);
     }
     std::string part_after_cursor = content.substr(index_after_cursor);
-    auto focused = (is_focused || hovered_) ? focus : select;
+    auto focused = (is_focused || hovered_) ? focusCursorBarBlinking : select;
     return hbox({
                text(part_before_cursor),
-               text(part_at_cursor) | focused | inverted | reflect(cursor_box_),
+               text(part_at_cursor) | focused | reflect(cursor_box_),
                text(part_after_cursor),
            }) |
            flex | frame | bold | main_decorator | reflect(box_);
diff --git a/src/ftxui/component/screen_interactive.cpp b/src/ftxui/component/screen_interactive.cpp
index 278c53cd3906756d2b9cbc2d8a1bc905edb84576..657487d25300da5a8c9517f50b6837fd50ac7891 100644
--- a/src/ftxui/component/screen_interactive.cpp
+++ b/src/ftxui/component/screen_interactive.cpp
@@ -512,8 +512,13 @@ void ScreenInteractive::Install() {
     });
   }
 
+  on_exit_functions.push([=] {
+    std::cout << "\033[?25h";  // Enable cursor.
+    std::cout << "\033[?1 q";  // Cursor block blinking.
+  });
+
   disable({
-      DECMode::kCursor,
+      //DECMode::kCursor,
       DECMode::kLineWrap,
   });
 
@@ -685,16 +690,26 @@ void ScreenInteractive::Draw(Component component) {
   set_cursor_position = "";
   reset_cursor_position = "";
 
-  int dx = dimx_ - 1 - cursor_.x;
-  int dy = dimy_ - 1 - cursor_.y;
+  {
+    int dx = dimx_ - 1 - cursor_.x;
+    int dy = dimy_ - 1 - cursor_.y;
 
-  if (dx != 0) {
-    set_cursor_position += "\x1B[" + std::to_string(dx) + "D";
-    reset_cursor_position += "\x1B[" + std::to_string(dx) + "C";
-  }
-  if (dy != 0) {
-    set_cursor_position += "\x1B[" + std::to_string(dy) + "A";
-    reset_cursor_position += "\x1B[" + std::to_string(dy) + "B";
+    if (dy != 0) {
+      set_cursor_position += "\x1B[" + std::to_string(dy) + "A";
+      reset_cursor_position += "\x1B[" + std::to_string(dy) + "B";
+    }
+
+    if (dx != 0) {
+      set_cursor_position += "\x1B[" + std::to_string(dx) + "D";
+      reset_cursor_position += "\x1B[" + std::to_string(dx) + "C";
+    }
+
+    if (cursor_.shape == Cursor::Hidden) {
+      set_cursor_position += "\033[?25l";
+    } else {
+      set_cursor_position += "\033[?25h";
+      set_cursor_position += "\033[" + std::to_string(int(cursor_.shape)) + " q";
+    }
   }
 
   std::cout << ToString() << set_cursor_position;
diff --git a/src/ftxui/dom/frame.cpp b/src/ftxui/dom/frame.cpp
index 575bbc84cedd57d7e5cf9aa835bac5f213d1931c..8aff60dcb1b5d67f0d97ca39f69fa281faa22826 100644
--- a/src/ftxui/dom/frame.cpp
+++ b/src/ftxui/dom/frame.cpp
@@ -71,7 +71,11 @@ class Focus : public Select {
     // https://github.com/microsoft/terminal/issues/1203
     // https://github.com/microsoft/terminal/issues/3093
 #if !defined(FTXUI_MICROSOFT_TERMINAL_FALLBACK)
-    screen.SetCursor(Screen::Cursor{box_.x_min, box_.y_min});
+    screen.SetCursor(Screen::Cursor{
+        box_.x_min,
+        box_.y_min,
+        Screen::Cursor::Shape::Hidden,
+    });
 #endif
   }
 };
@@ -147,6 +151,48 @@ Element yframe(Element child) {
   return std::make_shared<Frame>(unpack(std::move(child)), false, true);
 }
 
+class FocusCursor : public Focus {
+ public:
+  FocusCursor(Elements children, Screen::Cursor::Shape shape)
+      : Focus(std::move(children)), shape_(shape) {}
+
+ private:
+  void Render(Screen& screen) override {
+    Select::Render(screen);
+    screen.SetCursor(Screen::Cursor{
+        box_.x_min,
+        box_.y_min,
+        shape_,
+    });
+  }
+  Screen::Cursor::Shape shape_;
+};
+
+Element focusCursorBlock(Element child) {
+  return std::make_shared<FocusCursor>(unpack(std::move(child)),
+                                       Screen::Cursor::Block);
+}
+Element focusCursorBlockBlinking(Element child) {
+  return std::make_shared<FocusCursor>(unpack(std::move(child)),
+                                       Screen::Cursor::BlockBlinking);
+}
+Element focusCursorBar(Element child) {
+  return std::make_shared<FocusCursor>(unpack(std::move(child)),
+                                       Screen::Cursor::Bar);
+}
+Element focusCursorBarBlinking(Element child) {
+  return std::make_shared<FocusCursor>(unpack(std::move(child)),
+                                       Screen::Cursor::BarBlinking);
+}
+Element focusCursorUnderline(Element child) {
+  return std::make_shared<FocusCursor>(unpack(std::move(child)),
+                                       Screen::Cursor::Underline);
+}
+Element focusCursorUnderlineBlinking(Element child) {
+  return std::make_shared<FocusCursor>(unpack(std::move(child)),
+                                       Screen::Cursor::UnderlineBlinking);
+}
+
 }  // namespace ftxui
 
 // Copyright 2020 Arthur Sonzogni. All rights reserved.