Retroshare Web Interface: Final Update

The GSoC program is about to finish, and this will be my last GSoC-related blog post for Retroshare’s new web interface.

I will use this blog to provide an overview of how the app works, all my work done during this period, features, completed milestones, what couldn’t be completed, and future roadmap. I will also explain and document the code structure in the hopes that potential contributors will find it easy to get started.


The purpose is very simple; A web-app that can be used to manage your Retroshare node, interact with friend nodes, and make use of Retroshare’s features. In other words, an alternative to the Qt-based interface of the client app.

This is made possible through the JSON API provided by Retroshare, which allows everyone to utilize the power of Retroshare’s technology to create their own services, interfaces, or even build apps on top of Retroshare.

The web interface itself works in a pretty straightforward manner, making use of modern browsers to act as a front end for the Retroshare platform and it’s services. Made using JavaScript, and the only external library being used is Mithril, which is a very fast and lightweight framework for building single page web applications.

Build process

If you look at the source code, you can see that it is built using qmake, the config file executes build scripts in webui-src/make-src.

├── make-src/
│   ├── build.bat
│   ├──
│   ├── chat.css
│   ├── init.bat
│   ├──
│   ├── main.css
│   ├──
│   └── template.js

The build scripts in webui-src/make-src (most notably iterate over all files from the source directory(webui-src/app), copying files into their respective destinations.

All JavaScript files are compiled into app.js and CSS files into app.css, these compiled files are put into the destination directory which is webui. The build scripts also copy all the static files, from webui-src/assets over to the destination directory, maintaining their directory hierarchy. Static files are the ones that do not require any modification in order to be used, like the HTML, font files, some CSS styles, and so on.

Another important aspect of the build process is how it compiles all the JavaScript files into a single file.
Since CSS is simply a set of rules without any structure, the output file can be built simply by appending all the source .css files together, JavaScript however doesn’t work that way:

You may have noticed another file in make-src called template.js. This file is used to create an entry point for the JavaScript files. It can be thought of as a kind of polyfill for require. What this essentially does is, take all the .js source files and store them using objects in such a way that they are isolated from each other, and then enable interaction between them through exporting objects.

To make a module’s components public, we have to refer them in the module.exports object, and we can use them inside other modules by importing them using the require() method.
The module.exports object is the only data that can be accessed outside of the module.


Now that we know how require() and module.exports work, we can look into how the source code functions:

├── channels/
│   └── ...
├── chat/
│   └── ...
├── config/
│   └── ...
├── files/
│   └── ...
├── home.js
├── login.js
├── mail/
│   └── ...
├── main.js
├── mithril.js
├── network/
│   └── ...
├── people/
│   └── ...
├── rswebui.js
├── theme.css
└── widgets.js

The source files are all in webui-src/app. I have tried to implement a structure loosely based on the MVC design pattern. Aside from separating data and views as objects and components, it makes intuitive use of Mithril components and routing concepts.

Each folder contains the views and models for a single tab. All tabs have their own route resolver that takes in the route parameters and resolves them to return the correct views for rendering.

The entry point of all tabs happens in the resolver file, which also defines the layout of that tab. I will explain layout types shortly.

Note how the file names consist of their respective tab names too. This is not just for convention, our require polyfill does not yet have the concept of directory structure, any file present in any directory and may be imported by using only it’s name. This causes issues when accessing files having same names, which is why tab name supersedes the file name. It is important to have unique names for all files.

The main.js file contains mithril’s m.route, that defines the routing table and allows all navigation on the app. It detects whether the login keys have been verified and upon failing, reroutes to the login page using the onSuccess() callback.

The rswebui.js contains methods that act as the bridge between the web interface and the Retroshare client. Mainly, abstracting the API calls and managing async background tasks.

In a previous post, I mentioned that I did a lot of reading on UI and UX design, highlighting how it shaped the look and feel of the web interface.
After learning the importance of consistency when studying interaction design, I set out to make the interface more consistent.

In a nutshell, consistency refers to having uniformity in the UI, a form of repetition such that an action becomes predictable and intuitive to the user.

It can easily be achieved by having a predefined set of rules on how the UI should behave when interacted with, and the best way to do this is to make a set of reusable components. And since this is about the UI and visuals, it has more to do with CSS than JavaScript. Most of the layout rules are defined in theme.css.

The CSS class that houses all other widgets is the tab-page class. It’s the one containing all the elements under the navbar. All top level tab layouts use this and extend upon it. It can hold both full and half-width widgets, and position them according to the space taken by each.

The default blank layout created by the tab-page class.

The next is the sidebar class, which defines the sidebar on the left of some tabs, allowing to choose sub sections within the tab. It must be used when there are multiple sections but are logically grouped inside the same tab. Since this is a very commonly used widget, I have put this inside widgets.js, a file that contains a collection of the most used components, so that it is easily available everywhere. It takes in two parameters: the list of sections, and the base route link of the tab. Note that the section link must be the same as it’s name for it to be resolved properly:

m(widget.SideBar, {
    tabs: tabsList,
    baseRoute: '/route/',
sidebar class used in the config tab.

The widget class is used as a preliminary frame for displaying small groups of input types together. For consistency, a directly interactable input must never be shown directly inside tab-page, but must be inside at least one widget frame. For additional uniformity, I have been using the <h3> followed by the <hr> tags as the immediately following elements to display and categorize a frame’s contents.

A widget being used to create the interface for adding certificates.

The progressbar widget is a combination of a <span> tag relatively placed inside a <div> tag using the block-inline display attribute. To create the progressbar in mithril, just use:

m('.progressbar', {
    style: {
        content: rate + '%'
}, m('span.progress-status', {
    style: {
        width: rate + '%'
}, rate));
progressbars used in files tab.

And the CSS will handle the rest.

The tooltip widget can be used to display additional content when the mouse pointer is hovered over it. And can be easily created using:

m('.tooltip', [
    m('p', 'normally visible content'),
    m('.tooltiptext', 'content visible when hovered'),
Example use of tooltip.

A modal or popup box can be used to display content which might be triggered by a user’s action, or can display information that requires immediate attention of the user. This is also present in the widgets.js file. It is made as a mithril component, so can be used normally with the m() selector. It also takes in other mithril components as attributes, allowing it to display any given html tag.

widgets.popupMessage([/* Array of components to render */]);
The popup view used in files tab.

Creating custom input types making use of the <input> tag is incredibly easy in mithril, but may initially be confusing to programmers used to vanilla JavaScript for event handling.
Normally, to create a JS-controlled input field, you would do something like:

let text = document.getElementById('input').value;

But mithril components can be controlled very easily by making use of the onchange and oninput event handlers:

m('input[type=text]', {
    value: text,
    oninput: (e) => text =,

And text gets automatically updated with any value the user enters. Use oninput to get value after all the text is entered, and onchange for more finer control, which is fired every time a button is pressed. This method can be used with any input type like text, number, radio, checkbox, etc. and can be made to run any function, allowing for huge flexibility and control.


All the features and milestones that were successfully completed:

  • Get your certificate, add new friends by copying in their certificates.
  • View, manage your identities and get info about friend identities.
  • View and manage all your friend nodes and each of their locations, and basic info about them.
  • Get info about your upload/download files and manage them, add new downloads through links.
  • Check all your mails.
  • View info about subscribed chat lobbies and publicly available lobbies.
  • Change various configuration options of your Retroshare node such as network limits, file locations, default behavior, and such.


Retroshare has a huge amount of features, and unfortunately this period wasn’t enough for me to cover all of them into the web interface. I plan on implementing the incomplete tabs and then extending the app with new functionality:

  • Turtle search:
    As my mentor Cyril told me, this feature is very important since it makes it very easy to find and download new files, and is one of the features making use of stream data from the API.
    Getting stream data has been a problem due to CORS implemented on browsers, which is the reason this feature couldn’t be finished. I am constantly looking for a viable solution and will immediately finish implementing this when I find one.
  • Sending mails:
    The web interface can only read mails for now, and it would be very nice to be able to send mails too.
  • Forums:
    I have already started work on the forums tab, and will finish it soon. This will allow users to interact with and manage forums entirely from inside the web interface.
  • Channels:
    Similarly, I am also working on channels. Another nice feature to have on the Web UI.
  • Build Process:
    As shown above, the current build process is very barebones, and the require polyfill has no concept of directory hierarchy. This will eventually cause issues as the app grows. We need to upgrade the build tools, or find a new one. I think the most important point to keep in mind if choosing to go with a new one, is that the user should not have to install any additional dependencies.

That’s about it. I encourage everyone to try out the app, it is very easy to install the web interface. There are even simple installation instructions on the source page! Feel free to get in touch if you have any suggestions or queries. You can generally find me lurking in the Developer forums in Retroshare.

Many thanks to Google, and the amazing Freifunk community, especially my mentors, for giving me this opportunity. This has been a wonderful time for me, I learned a lot of new things that would help me contribute more towards free and open software.

Web Interface for Retroshare – Update 2

I Realized that the visual appearance of the application felt very bland and uninteresting, so I decided to shift some of my focus to the design and visual aspect of the UI. I did plenty of reading about UI/UX design principles and modern best practices during this time. And looks like it turned out pretty well, and is definitely a good improvement from the previous appearance. Also, since this is my first attempt at doing professional-level UX design, there is probably room for improvement, so feedback and suggestions are always welcome.

The general theme has been redone from scratch. I chose this soft blue color palette by taking inspiration from the main app’s look:

The home tab, along with displaying the user certificate, now also allows to add friends by using their certificates. It is possible to add friends by copying the certificate contents, dragging and dropping the file, or simply selecting it from the file manager.

Implemented modal messages within the browser that can be used as a popup dialogue box to display any kind of information (here showing information extracted from a Retroshare certificate):

As you can see, the navbar has also been revamped. And the best thing about it? Icons! I along with my mentors agreed on using the Font Awesome icon library, which is open source (licensed with a combination of MIT, CC 4.0 & OFL 1.1 licenses). I can now utilize icons across the whole app.

The downloads tab has also been redesigned. Now showing all downloads in a slightly different way. This layout was chosen with extensibility in mind, it can easily be extended to contain a additional file-related settings and chunk views by having an expandable options box for each file.

The config tab can now be used to change a lot of the setting options similar to the main app. Network, node, services, files and people sections from the app have been implemented. I will shortly finish the remaining sections too.

Also notice the tooltip icon. Which when hovered on, gives a brief description about the option. Just like in Retroshare:

Next steps

Now that the design is steadily making way for a more detailed and specialized variety of widgets and components, I am working on creating tabs for Network, People, Chats, Mail, Channels & Forums so that the Web Interface can finally become a fully usable alternative to the main client app.

You can try out the Web Interface by cloning it from the repository:, and my fork: Again, I am always happy to receive feedback and suggestions for improving the Web Interface.

Web Interface for Retroshare – Update 1

Since the first post, there has been quite a lot of progress on development of the new Web Interface for Retroshare.

As the build process is not using any JavaScript-specific tools, I spent a lot of time making sure that the development process was made as streamlined as possible. All the components are logically isolated and functionality moved to their relevant places. Using mithril also helped a lot, which has this concept of components, a mechanism to encapsulate different parts of views. Which massively helps in project organization and code reuse.

One more important feature which was completed is automatic data refresh and redrawing of views. I decided to use a combination of mithril’s lifecycle methods and JavaScript’s browser setTimeout method that can be used to create background tasks which when attached to their respective components, will periodically fetch and refresh data. The background task gets activated whenever a component’s view is rendered and gets killed when a component goes off of display. Mithril also has it’s own auto-redraw system which refreshes views when a component’s event handlers are called. But it does not refresh when component attributes are updated, or when raw promises are resolved.

Here are a few screenshots displaying the new UI style:

Next Steps

Along with the goals displayed in the first post, these will be given a higher priority for completion during the coming phase leading up to the next evaluation:

  • Node panel in config tab for handling most(if not all) network settings like node information, Net mode, NAT, Download limits, ports, etc.
  • Shares panel showing shared files, allowing to edit them, set view permissions, among other options.
  • Peers tab to display connected peers and set their reputations.
  • Modify the main Retroshare client to enable/disable the WebUI.

A new Web Interface for Retroshare

The Retroshare communication platform already has a preliminary web interface. But it is severely limited, supports only the basic of interactions with the client, and does not have the nice design and beautiful visual interface that the modern web platform makes possible. This GSoC project will be about creating an entirely new web interface for Retroshare using it’s JSON API to handle all communication between the WebUI and the client.

About Me

My name is Saud, I’m a third-year undergraduate student in Computer Science at Alliance University, Bangalore, India. This is my first time participating as a student in GSoC as well as my first time being involved in the Freifunk community.

Project briefing

The Web Interface is planned to be made in such a way that all communication with the client happens through the JSON API. As such, It will be made using JavaScript.

The Mithril web framework has been chosen chosen for designing the front-end as well as handling the API calls. Mithril is a very lightweight and fast client-side framework and is especially used for building single-page applications. It also provides neatly integrated and customizable XHR capabilities out of the box.

The old Web UI communicates with the client app entirely through the deprecated libresapi. The new UI will instead be using the JSON API for communication. The JSON API has already been implemented using Rapidjson. This makes it relatively easier to add new API headers to extend the interface and support more functionality.

Apart from this, one more important thing to keep in mind is that the WebUI is planned to replace the old interface and hopefully be shipped along with the main Retroshare app. And so it would make sense to keep dependencies to a minimum. This app will have a development process different from typical modern web dev practices. This app will not have dependencies(such as Nodejs), making it lightweight and able to easily integrate into the parent app’s build process.

A minimal working example has been implemented and can be seen in the source page.
Project source:
My fork:


A brief overview of the main goals to be expected from the project:

  • A “tab” system to display different sections of the Retroshare interface.
  • Detailed and asynchronously updating tabs about file transfers, downloads, adding peers, internal statistics, etc.
  • Options in the client app to enable and launch the WebUI.
  • A config panel with detailed frames for viewing and changing as many configuration options as possible.
  • Styled UI using CSS for a more sleek and beautiful look that adds to the visual appeal.
  • Replace the old WebUI and disable libresapi on merge.

The web interface would be extremely beneficial to the community, allowing Retroshare to leverage the flexibility and approachability of the web. It could be used by people who desire an alternate interface to Retroshare, for example, when using the nogui version, or due to the traditional GUI client being too demanding on low spec hardware, or due to the OS having problems with Qt, etc.

Looking forward to an exciting summer working on this project. I will post more updates soon.