diff --git a/_oasis b/_oasis
index 9c0c415e1452c822380a32d78d9af6ac1490faca..8fb6893fa04a404b33441fccefcc4b43808f4b78 100644
--- a/_oasis
+++ b/_oasis
@@ -88,7 +88,7 @@ Library interfacencurses
   CCOpt: -std=c++98 -x c++
   CSources:         Curses_stub.c, Readline_stub.c
   #InternalModules:
-  Modules:          Curses, Readline
+  Modules:          Curses, Readline, NCUI
 
 Executable coalg
   CompiledObject:   native
diff --git a/src/ncurses/Curses.ml b/src/ncurses/Curses.ml
index 066502b7f3aa91ee38e42caa3a350eb651d71f28..e29f596fd7d611df222865ab954ab46022bdd0a5 100644
--- a/src/ncurses/Curses.ml
+++ b/src/ncurses/Curses.ml
@@ -13,4 +13,5 @@ external addch: char -> unit = "curses_addch"
 external mvwaddch: window -> int -> int -> char -> unit = "curses_mvwaddch"
 external addstr: string -> unit = "curses_addstr"
 external mvwaddstr: window -> int -> int -> string -> unit = "curses_mvwaddstr"
+external getmaxyx: window -> int * int = "curses_getmaxyx"
 
diff --git a/src/ncurses/Curses.mli b/src/ncurses/Curses.mli
index ba96dc57151109c044f78ba4cda875aeb3460347..ac9b3697f0a8fdd33a91baa785a8aa3a1db1510b 100644
--- a/src/ncurses/Curses.mli
+++ b/src/ncurses/Curses.mli
@@ -12,3 +12,4 @@ val addch: char -> unit
 val mvwaddch: window -> int -> int -> char -> unit
 val addstr: string -> unit
 val mvwaddstr: window -> int -> int -> string -> unit
+val getmaxyx: window -> int * int
diff --git a/src/ncurses/Curses_stub.c b/src/ncurses/Curses_stub.c
index af4a03f223710893f14e78cebec857127edcf1f7..39ee0c0dbff17af11e185e35c791e9c15915ff44 100644
--- a/src/ncurses/Curses_stub.c
+++ b/src/ncurses/Curses_stub.c
@@ -100,4 +100,16 @@ value curses_mvwaddstr(value win, value x, value y, value s)
   CAMLreturn (Val_unit);
 }
 
+value curses_getmaxyx(value win)
+{
+  CAMLparam1 (win);
+  int h, w;
+  CAMLlocal1( hw );
+  hw = caml_alloc(2, 0);
+  getmaxyx(Window_val(win), h, w);
+  Store_field( hw, 0, Val_int(h) );
+  Store_field( hw, 1, Val_int(w) );
+  CAMLreturn ( hw );
+}
+
 }
diff --git a/src/ncurses/NCUI.ml b/src/ncurses/NCUI.ml
new file mode 100644
index 0000000000000000000000000000000000000000..eb647456d549c49769d857f67e33a8aed0b3ebf5
--- /dev/null
+++ b/src/ncurses/NCUI.ml
@@ -0,0 +1,70 @@
+(* a simple NCurses UI Library *)
+open Curses
+
+type point = int * int (* x and y *)
+
+type buffer = string list
+
+exception ScreenNotOpen
+exception NoRootWidget
+
+type 'a member = {
+    set : 'a -> unit;
+    get : unit -> 'a
+}
+
+type widget = {
+    minSize: point member;
+    paint: point -> buffer;
+}
+
+let member_init (v: 'a): 'a member =
+    let pointer = ref (v) in
+    {
+        set = (fun n -> pointer := v);
+        get = (fun () -> !pointer);
+    }
+
+let label str = {
+        minSize = member_init (0,0);
+        paint = (fun (w,h) -> [ str ]);
+    }
+
+let root_widget : widget option ref = ref (None)
+
+let get_root_widget () : widget =
+    match (!root_widget) with
+    | None -> raise NoRootWidget
+    | Some x -> x
+
+let stdscr : window option ref = ref (None)
+
+let screen_open  () =
+    stdscr := Some (initscr ())
+
+let get_stdscr () =
+    match (!stdscr) with
+    | None -> raise ScreenNotOpen
+    | Some x -> x
+
+let screen_close () =
+    stdscr := None;
+    endwin ()
+
+let paint_widget (wid:widget) ((x,y):point) (size: point) =
+    let stdscr = get_stdscr () in
+    let lines = wid.paint size in
+    let paint i str =
+        mvwaddstr stdscr (y+i) x str
+    in
+    List.iteri paint lines
+
+let update () =
+    let h, w = getmaxyx (get_stdscr ()) in
+    paint_widget (get_root_widget()) (0,0) (w,h);
+    refresh()
+
+let set_root_widget widget =
+    root_widget := Some widget;
+    update()
+
diff --git a/src/ncurses/NCUI.mli b/src/ncurses/NCUI.mli
new file mode 100644
index 0000000000000000000000000000000000000000..a67d16c57e6be8c1b880b357a2a9c2a21250c754
--- /dev/null
+++ b/src/ncurses/NCUI.mli
@@ -0,0 +1,28 @@
+(* a simple NCurses UI Library *)
+
+type point = int * int (* x and y *)
+
+type buffer = string list
+
+exception ScreenNotOpen
+exception NoRootWidget
+
+
+type 'a member = {
+    set : 'a -> unit;
+    get : unit -> 'a
+}
+
+type widget = {
+    minSize: point member;
+    paint: point -> buffer;
+}
+
+val member_init : 'a -> 'a member
+val label: string -> widget
+
+val update : unit -> unit
+val set_root_widget : widget -> unit
+val screen_open  : unit -> unit
+val screen_close : unit -> unit
+
diff --git a/src/repl-example/repl-example.ml b/src/repl-example/repl-example.ml
index 5f935619a7945e6c25b4b95936b1ba66ea144890..e87f607c9a670f033aa0aff71fb35f1ecc2c99bf 100644
--- a/src/repl-example/repl-example.ml
+++ b/src/repl-example/repl-example.ml
@@ -22,4 +22,10 @@ let main2 () =
   register_redraw redraw ;
   Readline.readline()
 
-let _ = main2 ()
+let main3 () =
+    NCUI.screen_open();
+    NCUI.set_root_widget (NCUI.label "HALLOOOO");
+    Unix.sleep 3;
+    NCUI.screen_close()
+
+let _ = main3 ()