diff --git a/.gitignore b/.gitignore
index 216f2ae65ac3bedf99496dc0b9561d86850acc7e..a3ecc43ad799290841c5695dfc0e3edecc0d80bb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
-.idea
-*.iml
-qrs_config.php
+/.idea
+/*.iml
+/node_modules
+/qrs_config.php
diff --git a/backend/Database.php b/backend/Database.php
index 18dfb5ff133bdfc64937636cdd03e2f96f10d93c..1fc2024be1c987ce56c001e46702a66dc06d115c 100644
--- a/backend/Database.php
+++ b/backend/Database.php
@@ -174,6 +174,7 @@ class Database {
 
     public function find(string $query, int $since = null, int $before = null, string $buffer = null, string $network = null, int $limitPerBuffer = 4) : array {
         $truncatedLimit = max(min($limitPerBuffer, 10), 0);
+        $truncatedLimit = 20;
 
         $buffers = $this->findBuffers($query, $since, $before, $buffer, $network);
         $messages = $this->findInBufferMultiple($query, $since, $before, $truncatedLimit);
diff --git a/package.json b/package.json
new file mode 100644
index 0000000000000000000000000000000000000000..2c15932435a98ea467e771372ff73b252cbb0740
--- /dev/null
+++ b/package.json
@@ -0,0 +1,22 @@
+{
+  "name": "quassel-rest-search",
+  "version": "3.0.0",
+  "description": "This is a websearch frontend for a quassel database.",
+  "scripts": {
+    "jsx": "node_modules/nativejsx/bin/nativejsx res/js/**/*.jsx",
+    "dep": "cp node_modules/nativejsx/dist/nativejsx-prototypes.js res/js/util/"
+  },
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/justjanne/quassel-rest-search.git"
+  },
+  "author": "Janne Koschinski",
+  "license": "GPL",
+  "bugs": {
+    "url": "https://github.com/justjanne/quassel-rest-search/issues"
+  },
+  "homepage": "https://github.com/justjanne/quassel-rest-search#readme",
+  "dependencies": {
+    "nativejsx": "^4.1.0"
+  }
+}
diff --git a/res/css/content.sass b/res/css/content.sass
index 60416a3dae51a60586dcd8e812bbd964d2f7392e..2472ccc462ba6d4354e860ec2cd90b58c4ed4a36 100644
--- a/res/css/content.sass
+++ b/res/css/content.sass
@@ -1,4 +1,5 @@
 @import "util"
+@import "sendercolor"
 
 .results
   max-width: 1136px
@@ -123,10 +124,8 @@
     &.selected
       background-color: #ddd
       border: rgba(0, 0, 0, .4)
-      padding: 20px 16px
-      margin-top: 20px
-      margin-left: -16px
-      margin-right: -16px
+      padding: 0 16px 20px
+      margin: 0 -16px
 
       @media(max-width: 800px)
         margin: 0 0 20px 0
@@ -147,16 +146,16 @@
 
       .container
         > .inline-button
-          display: block
+          height: 48px
 
     .container
       font-size: 13px
 
       > .inline-button
-        display: none
+        height: 0
+        overflow: hidden
         background: #f5f5f5
         font-size: 16px
-        height: 48px
         line-height: 48px
         color: rgb(113, 113, 113)
         text-align: center
@@ -165,8 +164,10 @@
         @include vendor-prefix('user-select', 'none')
         position: sticky
         bottom: 0
+        box-shadow: 0 -1px 0 #e5e5e5, 0 0 2px rgba(0, 0, 0, .12), 0 2px 4px rgba(0, 0, 0, .24)
+        transition: height 400ms
 
-        &:before
+        /*&:before
           bottom: 0
           box-shadow: 0 -1px 0 #e5e5e5, 0 0 2px rgba(0, 0, 0, .12), 0 2px 4px rgba(0, 0, 0, .24)
           content: ''
@@ -175,7 +176,7 @@
           pointer-events: none
           position: absolute
           right: 0
-          top: 0
+          top: 0*/
 
       .context
         .container
@@ -230,6 +231,7 @@
             display: flex
             flex-grow: 1
             flex-shrink: 1
+            overflow: hidden
 
             @media(max-width: 800px)
               display: block
@@ -253,6 +255,8 @@
 
             .preview
               flex: 50%
+              min-width: 0
+              overflow: hidden
 
               @media(max-width: 800px)
                 display: none
@@ -262,6 +266,7 @@
 
             .content
               flex: 50%
+              min-width: 0
               overflow: hidden
 
               @media(max-width: 800px)
diff --git a/res/css/search.css b/res/css/search.css
index 2459894a62f5371266435d60d793cf994e3f43c4..a5a16cf19d47a95fb7e1604a407288dbaadba227 100644
--- a/res/css/search.css
+++ b/res/css/search.css
@@ -211,6 +211,54 @@ body {
   .nav.focus + .results {
     opacity: 0; }
 
+[data-sendercolor="0"] {
+  color: #e90d7f; }
+
+[data-sendercolor="1"] {
+  color: #8e55e9; }
+
+[data-sendercolor="2"] {
+  color: #b30e0e; }
+
+[data-sendercolor="3"] {
+  color: #17b339; }
+
+[data-sendercolor="4"] {
+  color: #58afb3; }
+
+[data-sendercolor="5"] {
+  color: #9d54b3; }
+
+[data-sendercolor="6"] {
+  color: #b39775; }
+
+[data-sendercolor="7"] {
+  color: #3176b3; }
+
+[data-sendercolor="8"] {
+  color: #e90d7f; }
+
+[data-sendercolor="9"] {
+  color: #8e55e9; }
+
+[data-sendercolor="a"] {
+  color: #b30e0e; }
+
+[data-sendercolor="b"] {
+  color: #17b339; }
+
+[data-sendercolor="c"] {
+  color: #58afb3; }
+
+[data-sendercolor="d"] {
+  color: #9d54b3; }
+
+[data-sendercolor="e"] {
+  color: #b39775; }
+
+[data-sendercolor="f"] {
+  color: #3176b3; }
+
 .results {
   max-width: 1136px;
   padding: 56px 2rem 4rem 2rem;
@@ -319,10 +367,8 @@ body {
     .results .buffer.selected {
       background-color: #ddd;
       border: rgba(0, 0, 0, 0.4);
-      padding: 20px 16px;
-      margin-top: 20px;
-      margin-left: -16px;
-      margin-right: -16px; }
+      padding: 0 16px 20px;
+      margin: 0 -16px; }
 @media(max-width: 800px) {
   .results .buffer.selected {
     margin: 0 0 20px 0;
@@ -338,14 +384,14 @@ body {
         .results .buffer.selected .title button:before {
           content: "Close"; }
       .results .buffer.selected .container > .inline-button {
-        display: block; }
+        height: 48px; }
     .results .buffer .container {
       font-size: 13px; }
       .results .buffer .container > .inline-button {
-        display: none;
+        height: 0;
+        overflow: hidden;
         background: #f5f5f5;
         font-size: 16px;
-        height: 48px;
         line-height: 48px;
         color: #717171;
         text-align: center;
@@ -357,17 +403,19 @@ body {
         -o-user-select: none;
         user-select: none;
         position: sticky;
-        bottom: 0; }
-        .results .buffer .container > .inline-button:before {
-          bottom: 0;
-          box-shadow: 0 -1px 0 #e5e5e5, 0 0 2px rgba(0, 0, 0, 0.12), 0 2px 4px rgba(0, 0, 0, 0.24);
-          content: "";
-          display: block;
-          left: 0;
-          pointer-events: none;
-          position: absolute;
-          right: 0;
-          top: 0; }
+        bottom: 0;
+        box-shadow: 0 -1px 0 #e5e5e5, 0 0 2px rgba(0, 0, 0, 0.12), 0 2px 4px rgba(0, 0, 0, 0.24);
+        transition: height 400ms;
+        /*&:before
+         * bottom: 0
+         * box-shadow: 0 -1px 0 #e5e5e5, 0 0 2px rgba(0, 0, 0, .12), 0 2px 4px rgba(0, 0, 0, .24)
+         * content: ''
+         * display: block
+         * left: 0
+         * pointer-events: none
+         * position: absolute
+         * right: 0
+         * top: 0 */ }
       .results .buffer .container .context:not(.selected) > .before, .results .buffer .container .context:not(.selected) > .after {
         display: none; }
       .results .buffer .container .context:not(.selected) > .inline-button {
@@ -408,7 +456,8 @@ body {
         .results .buffer .container .context .message .container {
           display: flex;
           flex-grow: 1;
-          flex-shrink: 1; }
+          flex-shrink: 1;
+          overflow: hidden; }
 @media(max-width: 800px) {
   .results .buffer .container .context .message .container {
     display: block;
@@ -428,7 +477,9 @@ body {
     content: ": ";
     margin-right: 8px; } }
           .results .buffer .container .context .message .container .preview {
-            flex: 50%; }
+            flex: 50%;
+            min-width: 0;
+            overflow: hidden; }
 @media(max-width: 800px) {
   .results .buffer .container .context .message .container .preview {
     display: none; } }
@@ -436,6 +487,7 @@ body {
               background-color: rgba(251, 246, 167, 0.5); }
           .results .buffer .container .context .message .container .content {
             flex: 50%;
+            min-width: 0;
             overflow: hidden; }
 @media(max-width: 800px) {
   .results .buffer .container .context .message .container .content {
diff --git a/res/css/search.css.map b/res/css/search.css.map
index 995ec969a78e97c28557d53f2feca620e462a173..4ac5e9eae3449ff52a195062cc295dbec9ccdb21 100644
--- a/res/css/search.css.map
+++ b/res/css/search.css.map
@@ -1,7 +1,7 @@
 {
 "version": 3,
-"mappings": "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",
-"sources": ["icons.sass","font.sass","search.sass","nav.sass","util.sass","content.sass"],
+"mappings": "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",
+"sources": ["icons.sass","font.sass","search.sass","nav.sass","util.sass","sendercolor.sass","content.sass"],
 "names": [],
 "file": "search.css"
 }
\ No newline at end of file
diff --git a/res/css/sendercolor.sass b/res/css/sendercolor.sass
new file mode 100644
index 0000000000000000000000000000000000000000..30614938fe6f9a643637d289396bd99e79ba5c5a
--- /dev/null
+++ b/res/css/sendercolor.sass
@@ -0,0 +1,47 @@
+[data-sendercolor="0"]
+  color: #e90d7f
+  
+[data-sendercolor="1"]
+  color: #8e55e9
+
+[data-sendercolor="2"]
+  color: #b30e0e
+
+[data-sendercolor="3"]
+  color: #17b339
+
+[data-sendercolor="4"]
+  color: #58afb3
+
+[data-sendercolor="5"]
+  color: #9d54b3
+
+[data-sendercolor="6"]
+  color: #b39775
+
+[data-sendercolor="7"]
+  color: #3176b3
+
+[data-sendercolor="8"]
+  color: #e90d7f
+
+[data-sendercolor="9"]
+  color: #8e55e9
+
+[data-sendercolor="a"]
+  color: #b30e0e
+
+[data-sendercolor="b"]
+  color: #17b339
+
+[data-sendercolor="c"]
+  color: #58afb3
+
+[data-sendercolor="d"]
+  color: #9d54b3
+
+[data-sendercolor="e"]
+  color: #b39775
+
+[data-sendercolor="f"]
+  color: #3176b3
\ No newline at end of file
diff --git a/res/js/app.js b/res/js/app.js
index 19a5070b24edb299a7728cda10664f054dacf390..58a7a7902782406e928a3b943df59a55693944c4 100644
--- a/res/js/app.js
+++ b/res/js/app.js
@@ -1,6 +1,3 @@
-const senderColorHandler = new SenderColorHandler();
-const mircColorHandler = new MircColorHandler();
-
 class App {
     constructor() {
         this.navigation = new Navigation();
diff --git a/res/js/component/buffer.js b/res/js/component/buffer.js
deleted file mode 100644
index 0fbc9161b16e66c9d018ce7088b9a8e31a8dfe64..0000000000000000000000000000000000000000
--- a/res/js/component/buffer.js
+++ /dev/null
@@ -1,56 +0,0 @@
-class Buffer extends Component {
-    constructor(id, name, network, contextList = []) {
-        super();
-
-        this.id = id;
-        this.name = name;
-        this.network = network;
-        this.contextList = contextList;
-
-        this.render();
-    }
-
-    render() {
-        const buffer = document.createElement("div");
-            buffer.classList.add("buffer");
-            const title = document.createElement("div");
-                title.classList.add("title");
-                const titleHeader = document.createElement("h2");
-                    const titleValue = document.createTextNode(this.network + " - " + this.name);
-                    titleHeader.appendChild(titleValue);
-                title.appendChild(titleHeader);
-                const toggleButton = document.createElement("button");
-                    toggleButton.addEventListener("click", () => {
-                        this.selected();
-                    });
-                title.appendChild(toggleButton);
-            buffer.appendChild(title);
-            const contextWrap = document.createElement("div");
-                contextWrap.classList.add("container");
-                const loadMoreBtn = new LoadMore(translation.results.show_more);
-                loadMoreBtn.addEventListener("click", this.loadMore);
-                contextWrap.appendChild(loadMoreBtn.elem);
-            buffer.appendChild(contextWrap);
-        this.elem = buffer;
-        this.insertContainer = contextWrap;
-        this.loadMoreBtn = loadMoreBtn;
-
-        this.contextList.forEach((context) => this.insert(context));
-    }
-
-    loadMore() {
-        /* load data */
-    }
-
-    selected(isSelected) {
-        if (isSelected === undefined)
-            isSelected = !this.elem.classList.contains("selected");
-
-        this.elem.classList.toggle("selected", isSelected);
-        this.sendEvent("expanded", isSelected);
-    }
-
-    insert(context) {
-        this.insertContainer.insertBefore(context.elem, this.loadMoreBtn.elem);
-    }
-}
\ No newline at end of file
diff --git a/res/js/component/buffer.jsx b/res/js/component/buffer.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..afa3000b88f3731b670c5b0f18db2f704c1054dd
--- /dev/null
+++ b/res/js/component/buffer.jsx
@@ -0,0 +1,45 @@
+class Buffer extends Component {
+    constructor(id, name, network, contextList = []) {
+        super();
+
+        this.id = id;
+        this.name = name;
+        this.network = network;
+        this.contextList = contextList;
+
+        this.render();
+        this.contextList.forEach((context) => this.insert(context));
+    }
+
+    render() {
+        return this.elem = (
+            <div className="buffer">
+                <div className="title">
+                    <h2>{this.network} – {this.name}</h2>
+                    <button onClick={() => this.selected()}/>
+                </div>
+                {this.insertContainer = (
+                    <div className="container">
+                        {(this.loadMoreBtn = new LoadMore(translation.results.show_more, this.loadMore)).elem}
+                    </div>
+                )}
+            </div>
+        );
+    }
+
+    loadMore() {
+        /* load data */
+    }
+
+    selected(isSelected) {
+        if (isSelected === undefined)
+            isSelected = !this.elem.classList.contains("selected");
+
+        this.elem.classList.toggle("selected", isSelected);
+        this.sendEvent("expanded", isSelected);
+    }
+
+    insert(context) {
+        this.insertContainer.insertBefore(context.elem, this.loadMoreBtn.elem);
+    }
+}
\ No newline at end of file
diff --git a/res/js/component/context.js b/res/js/component/context.js
deleted file mode 100644
index 8b2e4cd93e3736a8301fb860505ddb0463136dfa..0000000000000000000000000000000000000000
--- a/res/js/component/context.js
+++ /dev/null
@@ -1,56 +0,0 @@
-class Context {
-    constructor(preview, beforeList=[], afterList=[]) {
-        this.preview = preview;
-        this.beforeList = beforeList;
-        this.afterList = afterList;
-
-        this.render();
-    }
-
-    render() {
-        const context = document.createElement("div");
-            context.classList.add("context");
-            const containerBefore = document.createElement("div");
-                containerBefore.classList.add("container");
-                containerBefore.classList.add("before");
-                const loadBeforeBtn = new LoadMore(translation.context.load_earlier);
-                loadBeforeBtn.addEventListener("click", this.loadBefore);
-                containerBefore.appendChild(loadBeforeBtn.elem);
-            context.appendChild(containerBefore);
-        
-            context.appendChild(this.preview.elem);
-        
-            const containerAfter = document.createElement("div");
-                containerAfter.classList.add("container");
-                containerAfter.classList.add("after");
-                const loadAfterBtn = new LoadMore(translation.context.load_later);
-                loadAfterBtn.addEventListener("click", this.loadAfter);
-                containerAfter.appendChild(loadAfterBtn.elem);
-            context.appendChild(containerAfter);
-        this.elem = context;
-        this.containerBefore = containerBefore;
-        this.loadBeforeBtn = loadBeforeBtn;
-        this.containerAfter = containerAfter;
-        this.loadAfterBtn = loadAfterBtn;
-        
-        this.beforeList.forEach(this.insertBefore);
-        this.afterList.forEach(this.insertAfter);
-    }
-
-    loadBefore() {
-        /* load data */
-    }
-
-    insertBefore(message) {
-        this.containerBefore.insertBefore(message.elem, this.insertBeforeTarget);
-        this.insertBeforeTarget = message.elem;
-    }
-
-    loadAfter() {
-        /* load data */
-    }
-
-    insertAfter(message) {
-        this.containerAfter.insertBefore(message.elem, this.insertAfterTarget);
-    }
-}
\ No newline at end of file
diff --git a/res/js/component/context.jsx b/res/js/component/context.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..877c7fa0341d74dc6f17a59ad90d0a87be3e4c3e
--- /dev/null
+++ b/res/js/component/context.jsx
@@ -0,0 +1,47 @@
+class Context {
+    constructor(preview, beforeList=[], afterList=[]) {
+        this.preview = preview;
+        this.beforeList = beforeList;
+        this.afterList = afterList;
+
+        this.render();
+        this.insertAfterTarget = this.loadAfterBtn;
+        this.beforeList.forEach(this.insertBefore);
+        this.afterList.forEach(this.insertAfter);
+    }
+
+    render() {
+        return this.elem = (
+            <div className="context">
+                {this.containerBefore = (
+                    <div className="container before">
+                        {(this.loadBeforeBtn = new LoadMore(translation.context.load_earlier, this.loadBefore)).elem}
+                    </div>
+                )}
+                {this.preview.elem}
+                {this.containerAfter = (
+                    <div className="container after">
+                        {(this.loadAfterBtn = new LoadMore(translation.context.load_later, this.loadAfter)).elem}
+                    </div>
+                )}
+            </div>
+        );
+    }
+
+    loadBefore() {
+        /* load data */
+    }
+
+    insertBefore(message) {
+        this.containerBefore.insertBefore(message.elem, this.insertBeforeTarget);
+        this.insertBeforeTarget = message.elem;
+    }
+
+    loadAfter() {
+        /* load data */
+    }
+
+    insertAfter(message) {
+        this.containerAfter.insertBefore(message.elem, this.insertAfterTarget);
+    }
+}
\ No newline at end of file
diff --git a/res/js/component/history.js b/res/js/component/history.jsx
similarity index 67%
rename from res/js/component/history.js
rename to res/js/component/history.jsx
index e69bb885eaed24794a0b6fbe195c3de75ccb701b..d1219ab27a745b09050905d3b14031de44b67c97 100644
--- a/res/js/component/history.js
+++ b/res/js/component/history.jsx
@@ -10,20 +10,19 @@ class HistoryView {
         });
 
         this.render();
+        this.elements.reverse().forEach((elem) => this.insert(elem));
     }
 
     render() {
-        const historyView = document.createElement("div");
-            historyView.classList.add("history");
-            const list = document.createElement("ul");
-                const noHistory = new NoHistoryElement();
-                list.appendChild(noHistory.elem);
-            historyView.appendChild(list);
-        this.elem = historyView;
-        this.list = list;
-        this.noHistory = noHistory;
-
-        this.elements.forEach((elem) => this.insert(elem));
+        return this.elem = (
+            <div className="history">
+                {this.list = (
+                    <ul>
+                        {(this.noHistory = new NoHistoryElement()).elem}
+                    </ul>
+                )}
+            </div>
+        );
     }
 
     insert(item) {
@@ -42,7 +41,7 @@ class HistoryView {
             this.elements.splice(idx, 1);
         }
 
-        this.elements.push(item);
+        this.elements.unshift(item);
         this.insert(item);
 
         this.truncate();
@@ -68,16 +67,32 @@ class HistoryView {
     }
 
     navigateBefore() {
+        if (this.elements[this.index])
+            this.elements[this.index].selected(false);
+
         this.index++;
         this.index %= this.elements.length;
+
+        if (this.elements[this.index])
+            this.elements[this.index].selected(true);
+
+        console.log(this.index);
     }
 
     navigateLater() {
+        if (this.elements[this.index])
+            this.elements[this.index].selected(false);
+
         this.index--;
         if (this.index < 0)
             this.index = -1;
         else
             this.index %= this.elements.length;
+
+        if (this.elements[this.index])
+            this.elements[this.index].selected(true);
+
+        console.log(this.index);
     }
 
     truncate() {
diff --git a/res/js/component/historyelement.js b/res/js/component/historyelement.js
deleted file mode 100644
index 2038671a1beb6abc268c50d6417ce24b18371185..0000000000000000000000000000000000000000
--- a/res/js/component/historyelement.js
+++ /dev/null
@@ -1,22 +0,0 @@
-class HistoryElement {
-    constructor(query) {
-        this.query = query;
-
-        this.render();
-    }
-
-    render() {
-        const wrapper = document.createElement("li");
-            const icon = document.createElement("span");
-                icon.classList.add("icon");
-                const iconValue = document.createTextNode("history");
-                icon.appendChild(iconValue);
-            wrapper.appendChild(icon);
-            const queryValue = document.createTextNode(this.query);
-            wrapper.appendChild(queryValue);
-        this.elem = wrapper;
-        this.elem.addEventListener("click", () => {
-            window.location.href = "#"+encodeURIComponent(this.query);
-        })
-    }
-}
\ No newline at end of file
diff --git a/res/js/component/historyelement.jsx b/res/js/component/historyelement.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..567c1d6922ad3893e55901958af93937fc1deb64
--- /dev/null
+++ b/res/js/component/historyelement.jsx
@@ -0,0 +1,23 @@
+class HistoryElement {
+    constructor(query) {
+        this.query = query;
+
+        this.render();
+        this.elem.addEventListener("click", () => {
+            window.location.href = "#"+encodeURIComponent(this.query);
+        });
+    }
+
+    render() {
+        return this.elem = (
+            <li>
+                <span className="icon">history</span>
+                {this.query}
+            </li>
+        );
+    }
+
+    selected(value) {
+        this.elem.classList.toggle("selected", value);
+    }
+}
\ No newline at end of file
diff --git a/res/js/component/loadmore.js b/res/js/component/loadmore.js
deleted file mode 100644
index 52edb1495ae67223f0edc217f94414da25b6e401..0000000000000000000000000000000000000000
--- a/res/js/component/loadmore.js
+++ /dev/null
@@ -1,11 +0,0 @@
-class LoadMore extends Component {
-    constructor(text) {
-        super();
-        const button = document.createElement("div");
-            button.classList.add("inline-button");
-            button.addEventListener("click", (event) => this.sendEvent("click", [event]));
-            const buttonValue = document.createTextNode(text);
-            button.appendChild(buttonValue);
-        this.elem = button;
-    }
-}
\ No newline at end of file
diff --git a/res/js/component/loadmore.jsx b/res/js/component/loadmore.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..b80d3c353088288e70f2c376183f4a070b82ec34
--- /dev/null
+++ b/res/js/component/loadmore.jsx
@@ -0,0 +1,16 @@
+class LoadMore extends Component {
+    constructor(text, eventListener) {
+        super();
+        this.render(text);
+        if (eventListener)
+            this.addEventListener("click", eventListener);
+    }
+
+    render(text) {
+        return this.elem = (
+            <div className="inline-button" onClick={(event) => this.sendEvent("click", [event])}>
+                {text}
+            </div>
+        );
+    }
+}
\ No newline at end of file
diff --git a/res/js/component/message.js b/res/js/component/message.js
deleted file mode 100644
index 66395e52f7ca4c8516f249a54c17591309ceb286..0000000000000000000000000000000000000000
--- a/res/js/component/message.js
+++ /dev/null
@@ -1,45 +0,0 @@
-class Message {
-    constructor(id, time, sender, content) {
-        this.id = id;
-        this.time = time;
-        this.sender = sender;
-        this.content = content;
-
-        this.render();
-    }
-
-    render() {
-        const message = document.createElement("div");
-            message.classList.add("message");
-            const time = document.createElement("time");
-                const timeValue = document.createTextNode(new Date(message.time.replace(" ", "T") + "Z").toLocaleString());
-                time.appendChild(timeValue);
-            message.appendChild(time);
-            const container = document.createElement("div");
-                container.classList.add("container");
-                const sender = document.createElement("div");
-                    sender.classList.add("sender");
-                    sender.style.color = senderColorHandler.nickToColor(this.getNick());
-                    const senderValue = document.createTextNode(this.getNick());
-                    sender.appendChild(senderValue);
-                container.appendChild(sender);
-                const content = document.createElement("div");
-                    content.classList.add("content");
-                    mircColorHandler.render(this.content).forEach((elem) => content.appendChild(elem));
-                container.appendChild(content);
-            message.appendChild(container);
-        this.elem = message;
-    }
-
-    getNick() {
-        return this.sender.split("!")[0];
-    }
-
-    getIdent() {
-        return this.sender.split("@")[0].split("!")[1];
-    }
-
-    getHost() {
-        return this.sender.split("@")[1];
-    }
-}
\ No newline at end of file
diff --git a/res/js/component/message.jsx b/res/js/component/message.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..af6cb9466a3b3c93449bf446337c67263154dae2
--- /dev/null
+++ b/res/js/component/message.jsx
@@ -0,0 +1,38 @@
+class Message {
+    constructor(id, time, sender, content) {
+        this.id = id;
+        this.time = time;
+        this.sender = sender;
+        this.content = content;
+
+        this.render();
+    }
+
+    render() {
+        return this.elem = (
+            <div className="message">
+                <time>{new Date(this.time.replace(" ", "T") + "Z").toLocaleString()}</time>
+                <div className="container">
+                    <div className="sender" data-sendercolor={SenderColorHandler.nickToColor(this.getNick())}>
+                        {this.getNick()}
+                    </div>
+                    <div className="content">
+                        {MircColorHandler.render(this.content)}
+                    </div>
+                </div>
+            </div>
+        );
+    }
+
+    getNick() {
+        return this.sender.split("!")[0];
+    }
+
+    getIdent() {
+        return this.sender.split("@")[0].split("!")[1];
+    }
+
+    getHost() {
+        return this.sender.split("@")[1];
+    }
+}
\ No newline at end of file
diff --git a/res/js/component/messagePreview.js b/res/js/component/messagePreview.js
deleted file mode 100644
index 27160d18b5b26213b729fdf441e275df70f03ea7..0000000000000000000000000000000000000000
--- a/res/js/component/messagePreview.js
+++ /dev/null
@@ -1,51 +0,0 @@
-class MessagePreview {
-    constructor(id, time, sender, content, preview) {
-        this.id = id;
-        this.time = time;
-        this.sender = sender;
-        this.content = content;
-        this.preview = preview;
-
-        this.render();
-    }
-
-    render() {
-        const message = document.createElement("div");
-            message.classList.add("message");
-            message.classList.add("preview");
-            const time = document.createElement("time");
-                const timeValue = document.createTextNode(new Date(this.time.replace(" ", "T") + "Z").toLocaleString());
-                time.appendChild(timeValue);
-            message.appendChild(time);
-            const container = document.createElement("div");
-                container.classList.add("container");
-                const sender = document.createElement("div");
-                    sender.classList.add("sender");
-                    sender.style.color = senderColorHandler.nickToColor(this.getNick());
-                    const senderValue = document.createTextNode(this.getNick());
-                    sender.appendChild(senderValue);
-                container.appendChild(sender);
-                const content = document.createElement("div");
-                    content.classList.add("content");
-                mircColorHandler.render(this.content).forEach((elem) => content.appendChild(elem));
-                container.appendChild(content);
-                const preview = document.createElement("div");
-                    preview.classList.add("preview");
-                mircColorHandler.highlight(this.preview).forEach((elem) => preview.appendChild(elem));
-                container.appendChild(preview);
-        message.appendChild(container);
-        this.elem = message;
-    }
-
-    getNick() {
-        return this.sender.split("!")[0];
-    }
-
-    getIdent() {
-        return this.sender.split("@")[0].split("!")[1];
-    }
-
-    getHost() {
-        return this.sender.split("@")[1];
-    }
-}
\ No newline at end of file
diff --git a/res/js/component/messagePreview.jsx b/res/js/component/messagePreview.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..b59d16bc5ed6d22e55c7465c50c8c4a51db81836
--- /dev/null
+++ b/res/js/component/messagePreview.jsx
@@ -0,0 +1,42 @@
+class MessagePreview {
+    constructor(id, time, sender, content, preview) {
+        this.id = id;
+        this.time = time;
+        this.sender = sender;
+        this.content = content;
+        this.preview = preview;
+
+        this.render();
+    }
+
+    render() {
+        return this.elem = (
+            <div className="message preview">
+                <time>{new Date(this.time.replace(" ", "T") + "Z").toLocaleString()}</time>
+                <div className="container">
+                    <div className="sender" data-sendercolor={SenderColorHandler.nickToColor(this.getNick())}>
+                        {this.getNick()}
+                    </div>
+                    <div className="content">
+                        {MircColorHandler.render(this.content)}
+                    </div>
+                    <div className="preview">
+                        {MircColorHandler.highlight(this.preview)}
+                    </div>
+                </div>
+            </div>
+        );
+    }
+
+    getNick() {
+        return this.sender.split("!")[0];
+    }
+
+    getIdent() {
+        return this.sender.split("@")[0].split("!")[1];
+    }
+
+    getHost() {
+        return this.sender.split("@")[1];
+    }
+}
\ No newline at end of file
diff --git a/res/js/component/nav.js b/res/js/component/nav.js
deleted file mode 100644
index b1e735c28d49fbe1e283e8e79e7c969c119deb38..0000000000000000000000000000000000000000
--- a/res/js/component/nav.js
+++ /dev/null
@@ -1,73 +0,0 @@
-const keyMapping = {
-    13: "Enter",
-    27: "Escape",
-    38: "ArrowUp",
-    40: "ArrowDown"
-};
-
-class Navigation extends Component {
-    constructor() {
-        super();
-        this.render();
-    }
-
-    render() {
-        const nav = document.createElement("div");
-            nav.classList.add("nav");
-            const bar = document.createElement("div");
-                bar.classList.add("bar");
-                const container = document.createElement("div");
-                    container.classList.add("container");
-                    const searchBar = document.createElement("div");
-                        searchBar.classList.add("searchBar");
-                        const searchIcon = document.createElement("div");
-                            searchIcon.classList.add("icon");
-                            const searchIconValue = document.createTextNode("search");
-                            searchIcon.appendChild(searchIconValue);
-                        searchBar.appendChild(searchIcon);
-                        const input = document.createElement("input");
-                            input.classList.add("search");
-                            input.placeholder = translation.search;
-                            input.type = "text";
-                            input.autocomplete = "off";
-                            input.addEventListener("focus", () => this.elem.classList.add("focus"));
-                            input.addEventListener("blur", () => this.elem.classList.remove("focus"));
-                            input.addEventListener("keydown", (e) => {
-                                switch (e.key || keyMapping[e.keyCode]) {
-                                    case "ArrowUp": {
-                                        this.historyView.navigateLater();
-                                    } break;
-                                    case "ArrowDown": {
-                                        this.historyView.navigateBefore();
-                                    } break;
-                                    case "Enter": {
-                                        this.sendEvent("search", [this.input.value]);
-                                        this.input.blur();
-                                    } break;
-                                    case "Escape": {
-                                        this.input.blur();
-                                    } break;
-                                }
-                            });
-                        searchBar.appendChild(input);
-                    container.appendChild(searchBar);
-                    const actions = document.createElement("div");
-                        actions.classList.add("actions");
-                        const logout = document.createElement("a");
-                            logout.title = translation.logout;
-                            logout.href = "login.php?action=logout";
-                            logout.classList.add("icon");
-                            const logoutValue = document.createTextNode("exit_to_app");
-                            logout.appendChild(logoutValue);
-                        actions.appendChild(logout);
-                    container.appendChild(actions);
-                bar.appendChild(container);
-            nav.appendChild(bar);
-            const historyView = new HistoryView();
-            nav.appendChild(historyView.elem);
-        this.elem = nav;
-
-        this.input = input;
-        this.historyView = historyView;
-    }
-}
\ No newline at end of file
diff --git a/res/js/component/nav.jsx b/res/js/component/nav.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..9c659a02e667da4786f87a11d8224edb170b848c
--- /dev/null
+++ b/res/js/component/nav.jsx
@@ -0,0 +1,62 @@
+const keyMapping = {
+    13: "Enter",
+    27: "Escape",
+    38: "ArrowUp",
+    40: "ArrowDown"
+};
+
+class Navigation extends Component {
+    constructor() {
+        super();
+        this.render();
+    }
+
+    render() {
+        return this.elem = (
+            <div className="nav">
+                <div className="bar">
+                    <div className="container">
+                        <div className="searchBar">
+                            <p className="icon">search</p>
+                            {this.input = (
+                                <input className="search" placeholder={translation.search} type="text"
+                                       autoComplete="off"
+                                       onFocus={() => this.elem.classList.add("focus")}
+                                       onBlur={() => this.elem.classList.remove("focus")}
+                                       onKeyDown={(e) => this.inputKeyDown(e)}
+                                />
+                            )}
+                        </div>
+                        <div className="actions">
+                            <a href="login.php?action=logout" title={translation.logout}
+                               className="icon">exit_to_app</a>
+                        </div>
+                    </div>
+                </div>
+                {(this.historyView = new HistoryView()).elem}
+            </div>
+        );
+    }
+
+    inputKeyDown(event) {
+        switch (event.key || keyMapping[event.keyCode]) {
+            case "ArrowUp":
+                this.historyView.navigateLater();
+                event.preventDefault();
+                break;
+            case "ArrowDown":
+                this.historyView.navigateBefore();
+                event.preventDefault();
+                break;
+            case "Enter":
+                this.sendEvent("search", [this.historyView.index === -1 ? this.input.value : this.historyView.elements[this.historyView.index].query]);
+                this.input.blur();
+                event.preventDefault();
+                break;
+            case "Escape":
+                this.input.blur();
+                event.preventDefault();
+                break;
+        }
+    }
+}
\ No newline at end of file
diff --git a/res/js/component/nohistoryelement.js b/res/js/component/nohistoryelement.js
deleted file mode 100644
index bfaed8023d95064e64fe1a0f23ee71c52a7d5a85..0000000000000000000000000000000000000000
--- a/res/js/component/nohistoryelement.js
+++ /dev/null
@@ -1,12 +0,0 @@
-class NoHistoryElement {
-    constructor() {
-        this.render();
-    }
-
-    render() {
-        const wrapper = document.createElement("p");
-            const value = document.createTextNode(translation.history.error_unavailable);
-            wrapper.appendChild(value);
-        this.elem = wrapper;
-    }
-}
\ No newline at end of file
diff --git a/res/js/component/nohistoryelement.jsx b/res/js/component/nohistoryelement.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..1a1ff0b25227d711427841c14fcad85aca6bf478
--- /dev/null
+++ b/res/js/component/nohistoryelement.jsx
@@ -0,0 +1,11 @@
+class NoHistoryElement {
+    constructor() {
+        this.render();
+    }
+
+    render() {
+        return this.elem = (
+            <p>{translation.history.error_unavailable}</p>
+        );
+    }
+}
\ No newline at end of file
diff --git a/res/js/util/mirccolorhandler.js b/res/js/util/mirccolorhandler.js
index f848f58c3def1ad3d9798d62342990787c035da1..25ca13f1b22e206387e134370ae4da5352ad6747 100644
--- a/res/js/util/mirccolorhandler.js
+++ b/res/js/util/mirccolorhandler.js
@@ -1,57 +1,65 @@
 class MircColorHandler {
-    render(text) {
-        const CODE_BOLD = "\x02";
-        const CODE_COLOR = "\x03";
-        const CODE_ITALIC = "\x1D";
-        const CODE_UNDERLINE = "\x1F";
-        const CODE_SWAP = "\x16";
-        const CODE_RESET = "\x0F";
-
+    static render(text) {
+        const CODE_BOLD = '\x02';
+        const CODE_COLOR = '\x03';
+        const CODE_ITALIC = '\x1D';
+        const CODE_UNDERLINE = '\x1F';
+        const CODE_SWAP = '\x16';
+        const CODE_RESET = '\x0F';
         const readNumber = function (str, start, end) {
             if (start >= end || start >= str.length)
                 return -1;
             else
                 return parseInt(str.substr(start, end), 10);
         };
-
         const findEndOfNumber = function (str, start) {
-            const validCharCodes = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"];
+            const validCharCodes = [
+                '0',
+                '1',
+                '2',
+                '3',
+                '4',
+                '5',
+                '6',
+                '7',
+                '8',
+                '9'
+            ];
             let i;
             let tmp = str.substr(start, 2);
             for (i = 0; i < 2 && i < tmp.length; i++) {
                 if (validCharCodes.indexOf(tmp.charAt(i)) === -1)
-                    break
+                    break;
             }
             return i + start;
         };
-
         const unescape = function (str) {
-            return str.replace(/&lt;/g, "<").replace(/&gt;/g, ">");
+            return str.replace(/&lt;/g, '<').replace(/&gt;/g, '>');
         };
-
         const fromState = function (state) {
-            const elem = document.createElement("span");
-            if (state.bold) elem.classList.add("irc_bold");
-            if (state.italic) elem.classList.add("irc_italic");
-            if (state.underline) elem.classList.add("irc_underline");
-            if (state.foreground!==null) elem.dataset["irc_foreground"] = state.foreground;
-            if (state.background!==null) elem.dataset["irc_background"] = state.background;
+            const elem = document.createElement('span');
+            if (state.bold)
+                elem.classList.add('irc_bold');
+            if (state.italic)
+                elem.classList.add('irc_italic');
+            if (state.underline)
+                elem.classList.add('irc_underline');
+            if (state.foreground !== null)
+                elem.dataset['irc_foreground'] = state.foreground;
+            if (state.background !== null)
+                elem.dataset['irc_background'] = state.background;
             return elem;
         };
-
         let apply = function (lastTag, str, i, normalCount, nodes) {
             const s = unescape(str.substr(i - normalCount, normalCount));
             if (normalCount === 0)
                 return;
-
             lastTag.appendChild(document.createTextNode(s));
             nodes.push(lastTag);
         };
-
         const formatString = function (str) {
             if (!str)
-                return document.createTextNode("");
-
+                return document.createTextNode('');
             let state = {
                 bold: false,
                 italic: false,
@@ -60,88 +68,74 @@ class MircColorHandler {
                 background: null
             };
             let lastTag = fromState(state);
-
             let nodes = [];
-
             let normalCount = 0;
             for (let i = 0; i < str.length; i++) {
                 const character = str.charAt(i);
                 switch (character) {
-                    case CODE_BOLD: {
+                case CODE_BOLD: {
                         apply(lastTag, str, i, normalCount, nodes);
                         normalCount = 0;
-
                         state.bold = !state.bold;
                         lastTag = fromState(state);
                     }
-                        break;
-                    case CODE_ITALIC: {
+                    break;
+                case CODE_ITALIC: {
                         apply(lastTag, str, i, normalCount, nodes);
                         normalCount = 0;
-
                         state.italic = !state.italic;
                         lastTag = fromState(state);
                     }
-                        break;
-                    case CODE_UNDERLINE: {
+                    break;
+                case CODE_UNDERLINE: {
                         apply(lastTag, str, i, normalCount, nodes);
                         normalCount = 0;
-
                         state.underline = !state.underline;
                         lastTag = fromState(state);
                     }
-                        break;
-                    case CODE_COLOR: {
+                    break;
+                case CODE_COLOR: {
                         apply(lastTag, str, i, normalCount, nodes);
                         normalCount = 0;
-
                         let foregroundStart = i + 1;
                         let foregroundEnd = findEndOfNumber(str, foregroundStart);
-
                         if (foregroundEnd > foregroundStart) {
                             let foreground = readNumber(str, foregroundStart, foregroundEnd);
-
                             let background = -1;
                             let backgroundStart = foregroundEnd + 1;
                             let backgroundEnd = -1;
-
                             if (str.length > foregroundEnd && str.charAt(foregroundEnd) === ',') {
                                 backgroundEnd = findEndOfNumber(str, backgroundStart);
                                 background = readNumber(str, backgroundStart, backgroundEnd);
                             }
-
                             if (state.foreground !== null) {
                                 if (background === -1)
                                     background = state.background;
                             }
-
                             state.foreground = foreground === -1 ? null : foreground;
                             state.background = background === -1 ? null : background;
                             lastTag = fromState(state);
-
-                            i = ((backgroundEnd === -1) ? foregroundEnd : backgroundEnd ) - 1;
+                            i = (backgroundEnd === -1 ? foregroundEnd : backgroundEnd) - 1;
                         } else if (state.foreground !== null) {
                             state.foreground = null;
                             state.background = null;
                             lastTag = fromState(state);
                         }
                     }
-                        break;
-                    case CODE_SWAP: {
+                    break;
+                case CODE_SWAP: {
                         apply(lastTag, str, i, normalCount, nodes);
                         normalCount = 0;
-
                         if (state.foreground != null) {
                             state.foreground = state.background;
                             state.background = state.foreground;
                             lastTag = fromState(state);
                         }
                     }
-                        break;
-                    case CODE_RESET: {
+                    break;
+                case CODE_RESET: {
                         apply(lastTag, str, i, normalCount, nodes);
                         normalCount = 0;
-
                         state.bold = false;
                         state.italic = false;
                         state.underline = false;
@@ -149,61 +143,43 @@ class MircColorHandler {
                         state.background = null;
                         lastTag = fromState(state);
                     }
-                        break;
-                    default: {
+                    break;
+                default: {
                         normalCount++;
                     }
-                        break;
+                    break;
                 }
             }
-
             apply(lastTag, str, str.length, normalCount, nodes);
-
             return nodes;
         };
-
         return formatString(text);
     }
-
-    highlight(text) {
+    static highlight(text) {
         let nodes = [];
-
         let highlight = false;
-
-        let patternStart = "<b>";
-        let patternEnd = "</b>";
-
+        let patternStart = '<b>';
+        let patternEnd = '</b>';
         let pattern = patternStart;
-
         let groupStart = 0;
-
         let addFragment = function () {
             const groupEnd = index === -1 ? text.length : index;
             if (groupStart == groupEnd)
                 return;
 
-            if (highlight) {
-                const highlightNode = document.createElement("span");
-                highlightNode.classList.add("irc_highlight");
-                highlightNode.appendChild(document.createTextNode(text.substr(groupStart, groupEnd - groupStart)));
-                nodes.push(highlightNode);
-            } else {
-                nodes.push(document.createTextNode(text.substr(groupStart, groupEnd - groupStart)));
-            }
+            const span = document.createElement('span');
+            if (highlight) span.classList.add("irc_highlight");
+            span.appendChildren(text.substr(groupStart, groupEnd - groupStart));
+            nodes.push(span);
         };
-
         let index = -1;
         while ((index = text.indexOf(pattern, groupStart)) < text.length && index > 0) {
             addFragment();
-
             groupStart = index + pattern.length;
             pattern = highlight ? patternStart : patternEnd;
-
             highlight = !highlight;
         }
-
         addFragment();
-
         return nodes;
     }
 }
\ No newline at end of file
diff --git a/res/js/util/sendercolorhandler.js b/res/js/util/sendercolorhandler.js
index ce757f21300a10f79efec8eca11c15e9a59614d1..9bcb7677e828f09c3f66d1e11814b61485d9bd3c 100644
--- a/res/js/util/sendercolorhandler.js
+++ b/res/js/util/sendercolorhandler.js
@@ -1,25 +1,4 @@
 class SenderColorHandler {
-    constructor(sendercolors = [
-        "#e90d7f",
-        "#8e55e9",
-        "#b30e0e",
-        "#17b339",
-        "#58afb3",
-        "#9d54b3",
-        "#b39775",
-        "#3176b3",
-        "#e90d7f",
-        "#8e55e9",
-        "#b30e0e",
-        "#17b339",
-        "#58afb3",
-        "#9d54b3",
-        "#b39775",
-        "#3176b3"
-    ]) {
-        this.sendercolors = sendercolors;
-    }
-
     static reflect(crc, n) {
         let j = 1, crcout = 0;
         for (let i = (1 << (n - 1)); i > 0; i >>= 1) {
@@ -62,7 +41,7 @@ class SenderColorHandler {
         return SenderColorHandler.qChecksum(nickToHash) & 0xF;
     }
 
-    nickToColor(nick) {
-        return this.sendercolors[SenderColorHandler.senderIndex(nick)];
+    static nickToColor(str) {
+        return SenderColorHandler.senderIndex(str).toString(16);
     }
 }
\ No newline at end of file
diff --git a/templates/search.phtml b/templates/search.phtml
index 0bf3f6e3b16f2f19d4a3c32a74f4f20a602afbc5..0491b77f2814b84913c4826c60c53851a5dc5e81 100644
--- a/templates/search.phtml
+++ b/templates/search.phtml
@@ -19,6 +19,7 @@
 <script>
     const translation = <?php echo json_encode($translation); ?>;
 </script>
+<script src="res/js/util/nativejsx-prototypes.js"></script>
 <script src="res/js/util/loader.js"></script>
 <script src="res/js/util/component.js"></script>
 <script src="res/js/util/mirccolorhandler.js"></script>